<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.5">
<title>APOC User Guide 3.2.3.6</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
/* Remove comment around @import statement below when using as a custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
audio,canvas,video{display:inline-block}
audio:not([controls]){display:none;height:0}
[hidden],template{display:none}
script{display:none!important}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
a{background:transparent}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.center{margin-left:auto;margin-right:auto}
.spread{width:100%}
p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:none}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.no-bullet{list-style:none}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite:before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
table thead,table tfoot{background:#f7f8f7;font-weight:bold}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
.clearfix:after,.float-group:after{clear:both}
*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
*:not(pre)>code.nobreak{word-wrap:normal}
*:not(pre)>code.nowrap{white-space:nowrap}
pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menu{color:rgba(0,0,0,.8)}
b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
b.button:before{content:"[";padding:0 3px 0 2px}
b.button:after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
#header:after,#content:after,#footnotes:after,#footer:after{clear:both}
#content{margin-top:1.25em}
#content:before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span:before{content:"\00a0\2013\00a0"}
#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark:before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber:after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media only screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
.sect1{padding-bottom:.625em}
@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
.sect1+.sect1{border-top:1px solid #efefed}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.listingblock>.content{position:relative}
.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
.listingblock:hover code[data-lang]:before{display:block}
.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
table.pyhltable td.code{padding-left:.75em;padding-right:0}
pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
pre.pygments .lineno{display:inline-block;margin-right:.25em}
table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
.quoteblock .quoteblock blockquote:before{display:none}
.verseblock{margin:0 1em 1.25em 1em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract{margin:0 0 1.25em 0;display:block}
.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
table.tableblock{max-width:100%;border-collapse:separate}
table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
table.frame-all{border-width:1px}
table.frame-sides{border-width:0 1px}
table.frame-topbot{border-width:1px 0}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
td>div.verse{white-space:pre}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
ul.inline>li>*{display:block}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
.colist>table tr>td:last-of-type{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background-color:#00fafa}
.black{color:#000}
.black-background{background-color:#000}
.blue{color:#0000bf}
.blue-background{background-color:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background-color:#fa00fa}
.gray{color:#606060}
.gray-background{background-color:#7d7d7d}
.green{color:#006000}
.green-background{background-color:#007d00}
.lime{color:#00bf00}
.lime-background{background-color:#00fa00}
.maroon{color:#600000}
.maroon-background{background-color:#7d0000}
.navy{color:#000060}
.navy-background{background-color:#00007d}
.olive{color:#606000}
.olive-background{background-color:#7d7d00}
.purple{color:#600060}
.purple-background{background-color:#7d007d}
.red{color:#bf0000}
.red-background{background-color:#fa0000}
.silver{color:#909090}
.silver-background{background-color:#bcbcbc}
.teal{color:#006060}
.teal-background{background-color:#007d7d}
.white{color:#bfbfbf}
.white-background{background-color:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background-color:#fafa00}
span.icon>.fa{cursor:default}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]:after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@media print{@page{margin:1.25cm .75cm}
*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]:after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
.sect1{padding-bottom:0!important}
.sect1+.sect1{border:0!important}
#header>h1:first-child{margin-top:1.25rem}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span:before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]:before{display:block}
#footer{background:none!important;padding:0 .9375em}
#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
</style>
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>APOC User Guide 3.2.3.6</h1>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#_introduction">Introduction</a>
<ul class="sectlevel2">
<li><a href="#_notices">Notices</a>
<ul class="sectlevel3">
<li><a href="#_license">License</a></li>
<li><a href="#__apoc_name_history">"APOC" Name history</a></li>
</ul>
</li>
<li><a href="#_installation">Installation</a>
<ul class="sectlevel3">
<li><a href="#_download_latest_release">Download latest release</a></li>
<li><a href="#_version_compatibility_matrix">Version Compatibility Matrix</a></li>
<li><a href="#_get_apoc_version">Get APOC Version</a></li>
<li><a href="#_using_apoc_with_neo4j_docker_image">Using APOC with Neo4j Docker image</a></li>
<li><a href="#_build_install_the_current_development_branch_from_source">Build &amp; install the current development branch from source</a></li>
</ul>
</li>
<li><a href="#_calling_procedures_functions_within_cypher">Calling Procedures &amp; Functions within Cypher</a></li>
<li><a href="#_procedure_function_signatures">Procedure &amp; Function Signatures</a></li>
</ul>
</li>
<li><a href="#_help_and_usage">Help and Usage</a></li>
<li><a href="#_overview_of_apoc_procedures_functions">Overview of APOC Procedures &amp; Functions</a></li>
<li><a href="#_user_defined_functions">User Defined Functions</a></li>
<li><a href="#_text_and_lookup_indexes">Text and Lookup Indexes</a>
<ul class="sectlevel2">
<li><a href="#_index_queries">Index Queries</a></li>
<li><a href="#_index_management">Index Management</a></li>
<li><a href="#_manual_indexes">Manual Indexes</a>
<ul class="sectlevel3">
<li><a href="#_data_used">Data Used</a></li>
<li><a href="#_using_manual_index_on_node_properties">Using Manual Index on Node Properties</a></li>
<li><a href="#_using_manual_index_on_relationship_properties">Using Manual Index on Relationship Properties</a></li>
</ul>
</li>
<li><a href="#_full_text_search">Full Text Search</a>
<ul class="sectlevel3">
<li><a href="#_advanced_search">Advanced Search</a></li>
<li><a href="#_fulltext_and_graph_search">Fulltext and Graph Search</a></li>
<li><a href="#_complex_searches">Complex Searches</a></li>
<li><a href="#_automatic_index_tracking_for_manual_indexes">Automatic Index Tracking for Manual Indexes</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#_utility_functions">Utility Functions</a>
<ul class="sectlevel2">
<li><a href="#_phonetic_text_procedures">Phonetic Text Procedures</a></li>
<li><a href="#_extract_domain">Extract Domain</a>
<ul class="sectlevel3">
<li><a href="#_timetolive_ttl_expire_nodes">TimeToLive (TTL) - Expire Nodes</a></li>
</ul>
</li>
<li><a href="#_date_and_time_conversions">Date and Time Conversions</a>
<ul class="sectlevel3">
<li><a href="#_conversion_between_formatted_dates_and_timestamps">Conversion between formatted dates and timestamps</a></li>
<li><a href="#_conversion_of_timestamps_between_different_time_units">Conversion of timestamps between different time units</a></li>
<li><a href="#_adding_subtracting_time_unit_values_to_timestamps">Adding/subtracting time unit values to timestamps</a></li>
<li><a href="#_current_timestamp">Current timestamp</a></li>
<li><a href="#_reading_separate_datetime_fields">Reading separate datetime fields:</a></li>
<li><a href="#_examples">Examples</a></li>
<li><a href="#_notes_on_formats">Notes on formats:</a></li>
<li><a href="#_reading_single_datetime_field_from_utc_epoch">Reading single datetime field from UTC Epoch:</a></li>
<li><a href="#_examples_2">Examples</a></li>
</ul>
</li>
<li><a href="#_number_format_conversions">Number Format Conversions</a>
<ul class="sectlevel3">
<li><a href="#_conversion_between_formatted_decimals">Conversion between formatted decimals</a></li>
<li><a href="#_examples_3">Examples</a></li>
</ul>
</li>
<li><a href="#_exact">Exact</a>
<ul class="sectlevel3">
<li><a href="#_handle_biginteger_and_bigdecimal">Handle BigInteger And BigDecimal</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#_graph_algorithms">Graph Algorithms</a>
<ul class="sectlevel2">
<li><a href="#_algorithm_procedures">Algorithm Procedures</a>
<ul class="sectlevel3">
<li><a href="#_community_detection_via_label_propagation">Community Detection via Label Propagation</a></li>
</ul>
</li>
<li><a href="#_expand_paths">Expand paths</a>
<ul class="sectlevel3">
<li><a href="#_expand">Expand</a></li>
<li><a href="#_expand_with_config">Expand with Config</a></li>
<li><a href="#_expand_to_nodes_in_a_subgraph">Expand to nodes in a subgraph</a></li>
<li><a href="#_expand_to_a_subgraph_and_return_all_nodes_and_relationships_within_the_subgraph">Expand to a subgraph and return all nodes and relationships within the subgraph</a></li>
<li><a href="#_expand_a_spanning_tree">Expand a spanning tree</a></li>
</ul>
</li>
<li><a href="#_centrality_algorithms">Centrality Algorithms</a>
<ul class="sectlevel3">
<li><a href="#_setup">Setup</a></li>
<li><a href="#_closeness_centrality_procedure">Closeness Centrality Procedure</a></li>
<li><a href="#_betweenness_centrality_procedure">Betweenness Centrality Procedure</a></li>
</ul>
</li>
<li><a href="#_pagerank_algorithm">PageRank Algorithm</a>
<ul class="sectlevel3">
<li><a href="#_setup_2">Setup</a></li>
<li><a href="#_pagerank_procedure">PageRank Procedure</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#_spatial">Spatial</a>
<ul class="sectlevel2">
<li><a href="#_spatial_functions">Spatial Functions</a>
<ul class="sectlevel3">
<li><a href="#_geocode">geocode</a></li>
<li><a href="#_configuring_geocode">Configuring Geocode</a></li>
<li><a href="#_configuring_custom_geocode_provider">Configuring Custom Geocode Provider</a></li>
<li><a href="#_using_geocode_within_a_bigger_cypher_query">Using Geocode within a bigger Cypher query</a></li>
<li><a href="#_calculating_distance_between_locations">Calculating distance between locations</a></li>
<li><a href="#_graph_refactoring">Graph Refactoring</a></li>
<li><a href="#_combined_space_and_time_search">Combined Space and Time search</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#_data_integration">Data Integration</a>
<ul class="sectlevel2">
<li><a href="#_load_json">Load JSON</a>
<ul class="sectlevel3">
<li><a href="#_load_json_2">Load JSON</a></li>
<li><a href="#_json_path">Json-Path</a></li>
<li><a href="#_load_json_stackoverflow_example">Load JSON StackOverflow Example</a></li>
<li><a href="#_load_json_from_twitter_with_additional_parameters">Load JSON from Twitter (with additional parameters)</a></li>
<li><a href="#_geocoding_example">GeoCoding Example</a></li>
</ul>
</li>
<li><a href="#_load_jdbc">Load JDBC</a>
<ul class="sectlevel3">
<li><a href="#_overview_database_integration">Overview: Database Integration</a></li>
<li><a href="#_mysql_example">MySQL Example</a></li>
<li><a href="#_load_jdbc_examples">Load JDBC Examples</a></li>
<li><a href="#_load_jdbc_with_params_examples">Load JDBC with params Examples</a></li>
<li><a href="#_load_data_in_transactional_batches">Load data in transactional batches</a></li>
<li><a href="#_cassandra_example">Cassandra Example</a></li>
<li><a href="#_support_for_hive_with_kerberos_auth">Support for Hive with Kerberos Auth</a></li>
<li><a href="#_load_jdbc_resources">LOAD JDBC - Resources</a></li>
</ul>
</li>
<li><a href="#_streaming_data_to_gephi">Streaming Data to Gephi</a>
<ul class="sectlevel4">
<li><a href="#_notes">Notes</a></li>
<li><a href="#_example">Example</a></li>
<li><a href="#_format">Format</a></li>
<li><a href="#_specifics_details">Specifics Details</a></li>
</ul>
</li>
<li><a href="#_elasticsearch_integration">ElasticSearch Integration</a>
<ul class="sectlevel3">
<li><a href="#_example_2">Example</a></li>
<li><a href="#_general_structure_and_parameters">General Structure and Parameters</a></li>
</ul>
</li>
<li><a href="#_load_xml">Load XML</a>
<ul class="sectlevel3">
<li><a href="#_load_xml_introduction">Load XML Introduction</a></li>
<li><a href="#_example_file">Example File</a></li>
<li><a href="#_simple_xml_format">Simple XML Format</a></li>
<li><a href="#_xpath">xPath</a></li>
<li><a href="#_load_xml_and_introspect">Load XML and Introspect</a></li>
<li><a href="#_extracting_datastructures">Extracting Datastructures</a></li>
<li><a href="#_import_xml_directly">import xml directly</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#_graph_refactorings">Graph Refactorings</a>
<ul class="sectlevel2">
<li><a href="#_graph_refactoring_procedures">Graph Refactoring Procedures</a>
<ul class="sectlevel3">
<li><a href="#_merging_nodes">Merging Nodes</a></li>
<li><a href="#_normalize_boolean_properties">Normalize boolean properties</a></li>
<li><a href="#_categorization">Categorization</a></li>
</ul>
</li>
<li><a href="#_using_cypher_and_apoc_to_move_a_property_value_to_a_label">Using Cypher and APOC to move a property value to a label</a></li>
</ul>
</li>
<li><a href="#_cypher_operations">Cypher Operations</a>
<ul class="sectlevel2">
<li><a href="#_running_cypher_fragments">Running Cypher fragments</a>
<ul class="sectlevel3">
<li><a href="#_example_fast_node_counts_by_label">Example: Fast Node-Counts by Label</a></li>
<li><a href="#_running_a_cypher_statement_timeboxed">Running a cypher statement timeboxed</a></li>
<li><a href="#_run_multiple_statements">Run multiple Statements</a></li>
<li><a href="#_run_cypher_script_files">Run Cypher Script Files</a></li>
<li><a href="#_conditional_cypher_execution">Conditional cypher execution</a></li>
</ul>
</li>
<li><a href="#_job_management_and_periodic_execution">Job management and periodic execution</a>
<ul class="sectlevel3">
<li><a href="#_introduction_asynchronous_transactional_execution">Introduction asynchronous transactional execution</a></li>
<li><a href="#_apoc_periodic_iterate">apoc.periodic.iterate</a></li>
<li><a href="#_apoc_periodic_commit">apoc.periodic.commit</a></li>
<li><a href="#_apoc_periodic_countdown">apoc.periodic.countdown</a></li>
<li><a href="#_further_functions">Further Functions</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#_virtual">Virtual</a>
<ul class="sectlevel2">
<li><a href="#_virtual_nodes_rels">Virtual Nodes/Rels</a>
<ul class="sectlevel3">
<li><a href="#_virtual_nodes_rels_example">Virtual Nodes/Rels Example</a></li>
</ul>
</li>
<li><a href="#_virtual_graph">Virtual Graph</a>
<ul class="sectlevel3">
<li><a href="#_virtual_graph_examples">Virtual Graph Examples</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#_triggers">Triggers</a>
<ul class="sectlevel4">
<li><a href="#_triggers_examples">Triggers Examples</a></li>
</ul>
</li>
<li><a href="#_schema">Schema</a>
<ul class="sectlevel4">
<li><a href="#_examples_4">Examples</a></li>
</ul>
</li>
<li><a href="#_atomic">Atomic</a>
<ul class="sectlevel2">
<li><a href="#_atomic_examples">Atomic Examples</a></li>
</ul>
</li>
<li><a href="#_bolt">Bolt</a>
<ul class="sectlevel2">
<li><a href="#_driver_configuration">Driver configuration</a></li>
<li><a href="#_bolt_examples">Bolt Examples</a></li>
</ul>
</li>
<li><a href="#_appendix_complete_overview">Appendix: Complete Overview</a>
<ul class="sectlevel2">
<li><a href="#_configuration_options">Configuration Options</a></li>
<li><a href="#_manual_indexes_2">Manual Indexes</a>
<ul class="sectlevel3">
<li><a href="#_index_queries_2">Index Queries</a></li>
<li><a href="#_index_management_2">Index Management</a></li>
<li><a href="#_schema_index_queries">Schema Index Queries</a></li>
</ul>
</li>
<li><a href="#_meta_graph">Meta Graph</a></li>
<li><a href="#_schema_2">Schema</a></li>
<li><a href="#_locking">Locking</a></li>
<li><a href="#_from_tojson">from/toJson</a></li>
<li><a href="#_export_import">Export / Import</a>
<ul class="sectlevel3">
<li><a href="#_export_to_csv">Export to CSV</a></li>
<li><a href="#_export_to_cypher_script">Export to Cypher Script</a></li>
<li><a href="#_roundtrip_example">Roundtrip Example</a></li>
</ul>
</li>
<li><a href="#_stream_back_exported_cypher_script_as_columns">Stream back Exported Cypher Script as columns</a></li>
<li><a href="#_examples_5">Examples</a>
<ul class="sectlevel3">
<li><a href="#_graphml_import_export">GraphML Import / Export</a></li>
</ul>
</li>
<li><a href="#_loading_data_from_rdbms">Loading Data from RDBMS</a></li>
<li><a href="#_loading_data_from_web_apis_json_xml_csv">Loading Data from Web-APIs (JSON, XML, CSV)</a></li>
<li><a href="#_interacting_with_elastic_search">Interacting with Elastic Search</a></li>
<li><a href="#_interacting_with_mongodb">Interacting with MongoDB</a></li>
<li><a href="#_interacting_with_couchbase">Interacting with Couchbase</a></li>
<li><a href="#_streaming_data_to_gephi_2">Streaming Data to Gephi</a></li>
<li><a href="#_creating_data">Creating Data</a></li>
<li><a href="#_paths">Paths</a></li>
<li><a href="#_virtual_nodes_rels_2">Virtual Nodes/Rels</a></li>
<li><a href="#_virtual_graph_2">Virtual Graph</a></li>
<li><a href="#_generating_graphs">Generating Graphs</a></li>
<li><a href="#_warmup">Warmup</a></li>
<li><a href="#_monitoring">Monitoring</a></li>
<li><a href="#_cypher_execution">Cypher Execution</a></li>
<li><a href="#_conditional_cypher_execution_2">Conditional Cypher Execution</a></li>
<li><a href="#_triggers_2">Triggers</a></li>
<li><a href="#_job_management">Job Management</a></li>
<li><a href="#_graph_refactoring_2">Graph Refactoring</a></li>
<li><a href="#_spatial_2">Spatial</a></li>
<li><a href="#_helpers">Helpers</a>
<ul class="sectlevel3">
<li><a href="#_aggregation_functions">Aggregation Functions</a></li>
<li><a href="#_static_value_storage">Static Value Storage</a></li>
<li><a href="#_conversion_functions">Conversion Functions</a></li>
<li><a href="#_map_functions">Map Functions</a></li>
<li><a href="#_collection_functions">Collection Functions</a></li>
<li><a href="#_lookup_and_manipulation_procedures">Lookup and Manipulation Procedures</a></li>
<li><a href="#_node_functions">Node Functions</a></li>
<li><a href="#_math_functions">Math Functions</a></li>
<li><a href="#_text_functions">Text Functions</a></li>
<li><a href="#_data_extraction">Data Extraction</a></li>
<li><a href="#_text_similarity_functions">Text Similarity Functions</a></li>
<li><a href="#_phonetic_comparison_functions">Phonetic Comparison Functions</a></li>
</ul>
</li>
<li><a href="#_utilities">Utilities</a></li>
<li><a href="#_config">Config</a></li>
<li><a href="#_time_to_live_ttl">Time to Live (TTL)</a></li>
<li><a href="#_date_time_support">Date/time Support</a>
<ul class="sectlevel3">
<li><a href="#_conversion_functions_between_formatted_dates_and_timestamps">Conversion Functions between formatted dates and timestamps</a></li>
<li><a href="#_conversion_of_timestamps_between_different_time_units_2">Conversion of timestamps between different time units</a></li>
<li><a href="#_adding_subtracting_time_unit_values_to_timestamps_2">Adding/subtracting time unit values to timestamps</a></li>
<li><a href="#_reading_separate_datetime_fields_2">Reading separate datetime fields</a></li>
<li><a href="#_reading_single_datetime_field_from_utc_epoch_2">Reading single datetime field from UTC epoch</a></li>
</ul>
</li>
<li><a href="#_current_timestamp_2">Current timestamp</a></li>
<li><a href="#_bitwise_operations">Bitwise operations</a></li>
<li><a href="#_path_expander">Path Expander</a>
<ul class="sectlevel3">
<li><a href="#_relationship_filter_2">Relationship Filter</a></li>
<li><a href="#_label_filter_2">Label Filter</a></li>
<li><a href="#_sequences_2">Sequences</a></li>
<li><a href="#_uniqueness">Uniqueness</a></li>
<li><a href="#_end_nodes_and_terminator_nodes">End nodes and terminator nodes</a></li>
</ul>
</li>
<li><a href="#_parallel_node_search">Parallel Node Search</a></li>
<li><a href="#_graph_algorithms_work_in_progress">Graph Algorithms (work in progress)</a></li>
</ul>
</li>
<li><a href="#_performance_tests">Performance Tests</a>
<ul class="sectlevel2">
<li><a href="#_import_and_export_to_cypher">Import and Export to Cypher</a></li>
<li><a href="#_script_to_execute_all_the_tests">Script to execute all the tests</a></li>
<li><a href="#_export_all">Export all</a>
<ul class="sectlevel3">
<li><a href="#_batch_size">Batch size</a></li>
<li><a href="#_different_output_formats">Different output formats</a></li>
<li><a href="#_many_files_separatefiles_config">Many files (separateFiles config)</a></li>
</ul>
</li>
<li><a href="#_export_from_query">Export from query</a>
<ul class="sectlevel3">
<li><a href="#_result_2">Result</a></li>
</ul>
</li>
<li><a href="#_export_from_given_nodes_and_rels">Export from given nodes and rels</a>
<ul class="sectlevel3">
<li><a href="#_result_3">Result</a></li>
</ul>
</li>
<li><a href="#_export_from_graph_object">Export from graph object</a>
<ul class="sectlevel3">
<li><a href="#_result_4">Result</a></li>
</ul>
</li>
<li><a href="#_import_schema_file">Import Schema file</a>
<ul class="sectlevel3">
<li><a href="#_result_5">Result</a></li>
</ul>
</li>
<li><a href="#_import_from_file">Import from file</a>
<ul class="sectlevel3">
<li><a href="#_runfile">runFile</a></li>
<li><a href="#_import_cypher_shell">Import cypher-shell</a></li>
<li><a href="#_import_neo4j_shell">Import neo4j-shell</a></li>
</ul>
</li>
<li><a href="#_import_and_export_to_graphml">Import and Export to GraphML</a></li>
<li><a href="#_script_to_execute_all_the_tests_2">Script to execute all the tests</a></li>
<li><a href="#_export_all_2">Export all</a>
<ul class="sectlevel3">
<li><a href="#_results_4">Results</a></li>
</ul>
</li>
<li><a href="#_export_graphml_from_query">Export GraphML from query</a>
<ul class="sectlevel3">
<li><a href="#_results_5">Results</a></li>
</ul>
</li>
<li><a href="#_export_graphml_from_graph_object">Export GraphML from Graph object</a>
<ul class="sectlevel3">
<li><a href="#_results_6">Results</a></li>
</ul>
</li>
<li><a href="#_export_graphml_from_given_nodes_and_rels">Export GraphML from given nodes and rels</a>
<ul class="sectlevel3">
<li><a href="#_results_7">Results</a></li>
</ul>
</li>
<li><a href="#_import_graphml">Import GraphML</a>
<ul class="sectlevel3">
<li><a href="#_import_on_gephi">Import on Gephi</a></li>
<li><a href="#_import_on_yed">Import on yEd</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="_introduction"><a class="link" href="#_introduction">Introduction</a></h2>
<div class="sectionbody">
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
Go here for documentation for APOC for Neo4j version <a href="index30.html">3.0.x</a> <a href="index31.html">3.1.x</a> <a href="index32.html">3.2.x</a>
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="_notices"><a class="link" href="#_notices">Notices</a></h3>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">
<div class="paragraph">
<p>Neo4j 3.2 has increased security for procedures and functions (aka sandboxing).
Procedures that use internal APIs have to be allowed in <code>$NEO4J_HOME/conf/neoj4.conf</code> with, e.g. <code>dbms.security.procedures.unrestricted=apoc.trigger.*,apoc.meta.*</code> for security reasons (or <code>apoc.*</code> for all).</p>
</div>
<div class="paragraph">
<p>If you want to use this via docker, you need to amend <code>-e NEO4J_dbms_security_procedures_unrestricted=apoc.\\\*</code> to your <code>docker run &#8230;&#8203;</code> command. The three backslashes are necessary to prevent wildcard expansions.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
<div class="paragraph">
<p>You can also whitelist procedures and functions in general to be loaded using: <code>dbms.security.procedures.whitelist=apoc.coll.*,apoc.load.*</code></p>
</div>
<div class="paragraph">
<p>Neo4j 3.2 introduces user defined aggregation functions, we will use that feature in APOC in the future, e.g. for export, graph-algorithms and more, instead of passing in Cypher statements to procedures.</p>
</div>
<div class="paragraph">
<p>Please note that about 70 procedures have been turned from procedures into user defined functions.
This includes, <code>apoc.date.* apoc.number.*, apoc.coll.*, apoc.map.*</code> and some more packages.
See, this <a href="https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/144">issue</a> for a list.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
Go here for documentation for APOC for Neo4j version <a href="index30.html">3.0.x</a> <a href="index31.html">3.1.x</a> <a href="index32.html">3.2.x</a>
</td>
</tr>
</table>
</div>
<div class="imageblock" style="float: right">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.gif" alt="apoc">
</div>
</div>
<div class="paragraph">
<p>Neo4j 3.0 introduced the concept of user defined procedures.
Those are custom implementations of certain functionality, that can&#8217;t be (easily) expressed in Cypher itself.
Those procedures are implemented in Java and can be easily deployed into your Neo4j instance, and then be called from Cypher directly.</p>
</div>
<div class="paragraph">
<p>The APOC library consists of many (about 300) procedures to help with many different tasks in areas like data integration, graph algorithms or data conversion.</p>
</div>
<div class="sect3">
<h4 id="_license"><a class="link" href="#_license">License</a></h4>
<div class="paragraph">
<p>Apache License 2.0</p>
</div>
</div>
<div class="sect3">
<h4 id="__apoc_name_history"><a class="link" href="#__apoc_name_history">"APOC" Name history</a></h4>
<div class="paragraph">
<p><a href="http://matrix.wikia.com/wiki/Apoc">Apoc</a> was the technician and driver on board of the Nebuchadnezzar in the Matrix movie. He was killed by Cypher.</p>
</div>
<div class="paragraph">
<p><strong>APOC</strong> was also the first bundled <a href="http://neo4j.com/blog/convenient-package-neo4j-apoc-0-1-released/">A Package Of Components</a> for Neo4j in 2009.</p>
</div>
<div class="paragraph">
<p><strong>APOC</strong> also stands for "Awesome Procedures On Cypher"</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_installation"><a class="link" href="#_installation">Installation</a></h3>
<div class="sect3">
<h4 id="_download_latest_release"><a class="link" href="#_download_latest_release">Download latest release</a></h4>
<div class="paragraph">
<p>Go to <a href="http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.2.3.6" class="bare">http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.2.3.6</a>
to find the latest release and download the binary jar to place into your <code>$NEO4J_HOME/plugins</code> folder.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
For <strong>Neo4j Desktop</strong> the <code>plugins</code> directory is in a different place, put the jar-file into these (make sure to replace all at upgrade).
See the <a href="https://neo4j.com/docs/operations-manual/current/configuration/file-locations/">Neo4j Manual</a> for more detail about the install locations.
</td>
</tr>
</table>
</div>
<div class="ulist">
<ul>
<li>
<p>OSX: <code>/Applications/Neo4j\ Community\ Edition\ &lt;version&gt;.app/Contents/Resources/app/plugins</code> <strong>AND</strong> <code>/Users/&lt;user&gt;/Documents/Neo4j/default.graphdb/plugins</code></p>
</li>
<li>
<p>Windows: <code>C:\Program Files\Neo4j CE &lt;version&gt;\plugins</code></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_version_compatibility_matrix"><a class="link" href="#_version_compatibility_matrix">Version Compatibility Matrix</a></h4>
<div class="paragraph">
<p>Since APOC relies in some places on Neo4j&#8217;s internal APIs you need to use the right APOC version for your Neo4j installaton.</p>
</div>
<div class="paragraph">
<p>Any version to be released after 1.1.0 will use a different, consistent versioning scheme: <code>&lt;neo4j-version&gt;.&lt;apoc&gt;</code> version. The trailing <code>&lt;apoc&gt;</code> part of the version number will be incremented with every apoc release.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc version</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">neo4j version</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.3.0.1">3.3.0.1</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.3.0 (3.3.x)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.2.3.5">3.2.3.5</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.2.3 (3.2.x)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.2.0.4">3.2.0.4</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.2.2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.2.0.3">3.2.0.3</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.2.0</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.1.3.9">3.1.3.9</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.1.6 (3.1.x)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.1.3.8">3.1.3.8</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.1.5</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.1.3.7">3.1.3.7</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.1.4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.1.2.5">3.1.2.5</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.1.2</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.1.0.4">3.1.0.4</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.1.0-3.1.1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/3.0.8.6">3.0.8.6</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.0.5-3.0.9 (3.0.x)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.0.4.3</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.0.4</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.1.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.0.0 - 3.0.3</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">1.0.0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3.0.0 - 3.0.3</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_get_apoc_version"><a class="link" href="#_get_apoc_version">Get APOC Version</a></h4>
<div class="paragraph">
<p>To know your current <code>apoc</code> version you can use the <strong>Function</strong> :</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">RETURN apoc.version()</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_using_apoc_with_neo4j_docker_image"><a class="link" href="#_using_apoc_with_neo4j_docker_image">Using APOC with Neo4j Docker image</a></h4>
<div class="paragraph">
<p>The <a href="https://hub.docker.com/_/neo4j/">Neo4j Docker image</a> allows to supply a volume for the <code>/plugins</code> folder. Download the APOC release fitting your Neo4j version to local folder <code>plugins</code> and provide it as a data volume:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">mkdir plugins
pushd plugins
wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.2.3.6/apoc-3.2.3.6-all.jar
popd
docker run --rm -e NEO4J_AUTH=none -p 7474:7474 -v $PWD/plugins:/plugins -p 7687:7687 neo4j:3.2.9</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you want to pass custom apoc config to your Docker instance, you can use environment variables, like here:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>docker run \
    -p 7474:7474 -p 7687:7687 \
    -v $PWD/data:/data -v $PWD/plugins:/plugins \
    --name neo4j-apoc \
    -e NEO4J_apoc_export_file_enabled=true \
    -e NEO4J_apoc_import_file_enabled=true \
    -e NEO4J_apoc_import_file_use__neo4j__config=true \
    neo4j</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_build_install_the_current_development_branch_from_source"><a class="link" href="#_build_install_the_current_development_branch_from_source">Build &amp; install the current development branch from source</a></h4>
<div class="listingblock">
<div class="content">
<pre>git clone http://github.com/neo4j-contrib/neo4j-apoc-procedures
./gradlew shadow
cp build/libs/apoc-&lt;version&gt;-SNAPSHOT-all.jar $NEO4J_HOME/plugins/
$NEO4J_HOME/bin/neo4j restart</pre>
</div>
</div>
<div class="paragraph">
<p>A full build including running the tests can be run by <code>./gradlew build</code>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_calling_procedures_functions_within_cypher"><a class="link" href="#_calling_procedures_functions_within_cypher">Calling Procedures &amp; Functions within Cypher</a></h3>
<div class="paragraph">
<p>User defined <strong>Functions</strong> can be used in <strong>any</strong> expression or predicate, just like built-in functions.</p>
</div>
<div class="paragraph">
<p><strong>Procedures</strong> can be called stand-alone with <code>CALL procedure.name();</code></p>
</div>
<div class="paragraph">
<p>But you can also integrate them into your Cypher statements which makes them so much more powerful.</p>
</div>
<div class="listingblock">
<div class="title">Load JSON example</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH 'https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/{branch}/src/test/resources/person.json' AS url

CALL apoc.load.json(url) YIELD value as person

MERGE (p:Person {name:person.name})
   ON CREATE SET p.age = person.age, p.children = size(person.children)</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_procedure_function_signatures"><a class="link" href="#_procedure_function_signatures">Procedure &amp; Function Signatures</a></h3>
<div class="paragraph">
<p>To call procedures correctly, you need to know their parameter names, types and positions.
And for YIELDing their results, you have to know the output column names and types.</p>
</div>
<div class="paragraph">
<p>INFO: The signatures are shown in error messages, if you use a procedure incorrectly.</p>
</div>
<div class="paragraph">
<p>You can see the procedures signature in the output of <code>CALL apoc.help("name")</code> (which itself uses <code>CALL dbms.procedures()</code> and <code>CALL dbms.functions()</code>)</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.help("dijkstra")</code></pre>
</div>
</div>
<div class="paragraph">
<p>The signature is always <code>name : : TYPE</code>, so in this case:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>apoc.algo.dijkstra
 (startNode :: NODE?, endNode :: NODE?,
   relationshipTypesAndDirections :: STRING?, weightPropertyName :: STRING?)
:: (path :: PATH?, weight :: FLOAT?)</pre>
</div>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 1. Parameter Explanation</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Type</th>
</tr>
</thead>
<tbody>
<tr>
<th class="tableblock halign-left valign-top"><p class="tableblock">Procedure Parameters</p></th>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>startNode</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Node</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>endNode</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Node</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>relationshipTypesAndDirections</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>weightPropertyName</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
</tr>
<tr>
<th class="tableblock halign-left valign-top"><p class="tableblock">Output Return Columns</p></th>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>path</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Path</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Float</code></p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_help_and_usage"><a class="link" href="#_help_and_usage">Help and Usage</a></h2>
<div class="sectionbody">
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc-help-apoc.jpg" alt="apoc help apoc" width="600">
</div>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.help('search')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">lists name, description-text and if the procedure performs writes, search string is checked against beginning (package) or end (name) of procedure</p></td>
</tr>
</tbody>
</table>
<div class="listingblock">
<div class="title">helpful</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.help("apoc") YIELD name, text
WITH * WHERE text IS null
RETURN name AS undocumented</code></pre>
</div>
</div>
<div class="paragraph">
<p>To generate the help output, apoc utilizes the built in <code>dbms.procedures()</code> and <code>dbms.functions()</code> utilities.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_overview_of_apoc_procedures_functions"><a class="link" href="#_overview_of_apoc_procedures_functions">Overview of APOC Procedures &amp; Functions</a></h2>
<div class="sectionbody">
<table id="table-all" class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">type</th>
<th class="tableblock halign-left valign-top">qualified name</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.list</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.list - list all jobs</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.commit</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.commit(statement,params) - runs the given statement in separate transactions until it returns 0</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.cancel</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.cancel(name) - cancel job with the given name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.submit</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.submit('name',statement) - submit a one-off background statement</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.repeat</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.repeat('name',statement,repeat-rate-in-seconds) submit a repeatedly-called background statement</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.countdown</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.countdown('name',statement,repeat-rate-in-seconds) submit a repeatedly-called background statement until it returns 0</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.rock_n_roll_while</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.rock_n_roll_while('some cypher for knowing when to stop', 'some cypher for iteration', 'some cypher as action on each iteration', 10000) YIELD batches, total - run the action statement in batches over the iterator statement&#8217;s results in a separate thread. Returns number of batches and total processed rows</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.iterate</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.iterate('statement returning items', 'statement per item', {batchSize:1000,iterateList:false,parallel:true}) YIELD batches, total - run the second statement for each item returned by the first statement. Returns number of batches and total processed rows</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.rock_n_roll</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.rock_n_roll('some cypher for iteration', 'some cypher as action on each iteration', 10000) YIELD batches, total - run the action statement in batches over the iterator statement&#8217;s results in a separate thread. Returns number of batches and total processed rows</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cluster.graph</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.monitor.locks</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.monitor.locks(minWaitTime) yield advertedDeadLocks, lockCount, contendedLockCount, minimumWaitTimeMs, contendedLocks, info</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.monitor.kernel</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.monitor.kernel() returns informations about the neo4j kernel</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.monitor.store</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.monitor.store() returns informations about the sizes of the different parts of the neo4j graph store</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.monitor.ids</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.monitor.ids() returns the object ids in use for this neo4j instance</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.monitor.tx</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.monitor.tx() returns informations about the neo4j transaction manager</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.trigger.add</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.trigger.remove</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.trigger.list</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.trigger.pause</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.trigger.resume</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.static.get</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.static.get(name) - returns statically stored value from config (apoc.static.&lt;key&gt;) or server lifetime storage</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.static.getAll</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.static.getAll(prefix) - returns statically stored values from config (apoc.static.&lt;prefix&gt;.*) or server lifetime storage</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.static.list</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.static.list(prefix) - returns statically stored values from config (apoc.static.&lt;prefix&gt;.*) or server lifetime storage</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.static.set</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.static.set(name, value) - stores value under key for server livetime storage, returns previously stored or configured value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.sleep</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.sleep(&lt;duration&gt;) | sleeps for &lt;duration&gt; millis, transaction termination is honored</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.validate</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.validate(predicate, message, params) | if the predicate yields to true raise an exception</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.merge.node</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.merge.node(['Label'], {key:value, &#8230;&#8203;}, {key:value,&#8230;&#8203;}) - merge node with dynamic labels</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.merge.relationship</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.merge.relationship(startNode, relType,  {key:value, &#8230;&#8203;}, {key:value, &#8230;&#8203;}, endNode) - merge relationship with dynamic type</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bolt.load</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bolt.execute</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.config.list</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.config.map</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.link</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.link([nodes],'REL_TYPE') - creates a linked list of nodes from first to last</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.get</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.get(node|nodes|id|[ids]) - quickly returns all nodes with these id&#8217;s</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.delete</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.delete(node|nodes|id|[ids]) - quickly delete all nodes with these id&#8217;s</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.rels</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.get.rels(rel|id|[ids]) - quickly returns all relationships with these id&#8217;s</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.group</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.example.movies</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.example.movies() | Creates the sample movies graph</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.path.expand</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.path.expand(startNode &lt;id&gt;|Node|list, 'TYPE|TYPE_OUT&gt;|&lt;TYPE_IN', '+YesLabel|-NoLabel', minLevel, maxLevel ) yield path expand from start node following the given relationships from min to max-level adhering to the label filters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.path.expandConfig</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.path.expandConfig(startNode &lt;id&gt;|Node|list, {minLevel,maxLevel,uniqueness,relationshipFilter,labelFilter,uniqueness:'RELATIONSHIP_PATH',bfs:true, filterStartNode:false}) yield path expand from start node following the given relationships from min to max-level adhering to the label filters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.path.subgraphNodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.path.subgraphNodes(startNode &lt;id&gt;|Node|list, {maxLevel,relationshipFilter,labelFilter,bfs:true, filterStartNode:false}) yield node expand the subgraph nodes reachable from start node following relationships to max-level adhering to the label filters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.path.subgraphAll</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.path.subgraphAll(startNode &lt;id&gt;|Node|list, {maxLevel,relationshipFilter,labelFilter,bfs:true, filterStartNode:false}) yield nodes, relationships expand the subgraph reachable from start node following relationships to max-level adhering to the label filters, and also return all relationships within the subgraph</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.path.spanningTree</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.path.spanningTree(startNode &lt;id&gt;|Node|list, {maxLevel,relationshipFilter,labelFilter,bfs:true, filterStartNode:false}) yield path expand a spanning tree reachable from start node following relationships to max-level adhering to the label filters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.expire</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.date.expire(node,time,'time-unit') - expire node in given time by setting :TTL label and <code>ttl</code> property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.expireIn</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.date.expire.in(node,time,'time-unit') - expire node in given time-delta by setting :TTL label and <code>ttl</code> property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.fromData</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.fromData([nodes],[relationships],'name',{properties}) | creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.from</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.from(data,'name',{properties}) | creates a virtual graph object for later processing it tries its best to extract the graph information from the data you pass in</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.fromPath</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.fromPaths(path,'name',{properties}) - creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.fromPaths</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.fromPaths([paths],'name',{properties}) - creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.fromDB</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.fromDB('name',{properties}) - creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.fromCypher</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.graph.fromCypher('statement',{params},'name',{properties}) - creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.lock.all</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.lock.all([nodes],[relationships]) acquires a write lock on the given nodes and relationships</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.lock.nodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.lock.nodes([nodes]) acquires a write lock on the given nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.lock.read.nodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.lock.read.nodes([nodes]) acquires a read lock on the given nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.lock.rels</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.lock.rels([relationships]) acquires a write lock on the given relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.lock.read.rels</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.lock.read.rels([relationships]) acquires a read lock on the given relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.aStar</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.aStar(startNode, endNode, 'KNOWS|&lt;WORKS_WITH|IS_MANAGER_OF&gt;', 'distance','lat','lon') YIELD path, weight - run A* with relationship property name as cost function</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.aStarConfig</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.aStar(startNode, endNode, 'KNOWS|&lt;WORKS_WITH|IS_MANAGER_OF&gt;', {weight:'dist',default:10,x:'lon',y:'lat'}) YIELD path, weight - run A* with relationship property name as cost function</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.dijkstra</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.dijkstra(startNode, endNode, 'KNOWS|&lt;WORKS_WITH|IS_MANAGER_OF&gt;', 'distance') YIELD path, weight - run dijkstra with relationship property name as cost function</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.allSimplePaths</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.allSimplePaths(startNode, endNode, 'KNOWS|&lt;WORKS_WITH|IS_MANAGER_OF&gt;', 5) YIELD path, weight - run allSimplePaths with relationships given and maxNodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.dijkstraWithDefaultWeight</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.dijkstraWithDefaultWeight(startNode, endNode, 'KNOWS|&lt;WORKS_WITH|IS_MANAGER_OF&gt;', 'distance', 10) YIELD path, weight - run dijkstra with relationship property name as cost function and a default weight if the property does not exist</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.cover</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.cover(nodes) yield rel - returns all relationships between this set of nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.cliques</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.cliques(minSize) YIELD cliques - search the graph and return all maximal cliques at least at large as the minimum size argument.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.cliquesWithNode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.cliquesWithNode(startNode, minSize) YIELD cliques - search the graph and return all maximal cliques that are at least as large than the minimum size argument and contain this node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.wcc</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.algo.wcc() YIELD number of weakly connected components</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.pageRank</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.algo.pageRank(nodes) YIELD node, score - calculates page rank for given nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.pageRankWithConfig</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.algo.pageRankWithConfig(nodes,{iterations:_,types:_}) YIELD node, score, info - calculates page rank for given nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.pageRankStats</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.algo.pageRankStats({iterations:_,types:_,write:true,&#8230;&#8203;}) YIELD nodeCount - calculates page rank on graph  for given nodes and potentially writes back</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.pageRankWithCypher</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.algo.pageRankWithCypher({iterations,node_cypher,rel_cypher,write,property,numCpu}) - calculates page rank based on cypher input</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.betweenness</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.algo.betweenness(['TYPE',&#8230;&#8203;],nodes,BOTH) YIELD node, score - calculate betweenness centrality for given nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.betweennessCypher</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.algo.betweennessCypher(node_cypher,rel_cypher,write) - calculates betweeness  centrality based on cypher input</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.closeness</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.algo.closeness(['TYPE',&#8230;&#8203;],nodes, INCOMING) YIELD node, score - calculate closeness centrality for given nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.community</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.algo.community(times,labels,partitionKey,type,direction,weightKey,batchSize) - simple label propagation kernel</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.stats</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.stats  yield labelCount, relTypeCount, propertyKeyCount, nodeCount, relCount, labels, relTypes, stats | returns the information stored in the transactional database statistics</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.data</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.data  - examines a subset of the graph to provide a tabular meta information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.schema</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.schema  - examines a subset of the graph to provide a map-like meta information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.graph</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.graph - examines the full graph to create the meta-graph</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.graphSample</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.graphSample() - examines the database statistics to build the meta graph, very fast, might report extra relationships</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.subGraph</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.subGraph({labels:[labels],rels:[rel-types], excludes:[labels,rel-types]}) - examines a sample sub graph to create the meta-graph</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.get.nodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.get.nodes(node|id|[ids]) - quickly returns all nodes with these id&#8217;s</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.get.rels</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.get.rels(rel|id|[ids]) - quickly returns all relationships with these id&#8217;s</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.run</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.run(fragment, params) yield value - executes reading fragment with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runFile</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runFile(file or url) - runs each statement in the file, all semicolon separated - currently no schema operations</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runFiles</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runFiles([files or urls]) - runs each statement in the files, all semicolon separated</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runSchemaFile</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runSchemaFile(file or url) - allows only schema operations, runs each schema statement in the file, all semicolon separated</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runSchemaFiles</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runSchemaFiles([files or urls]) - allows only schema operations, runs each schema statement in the files, all semicolon separated</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runMany</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runMany('cypher;\nstatements;',{params}) - runs each semicolon separated statement and returns summary - currently no schema operations</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.parallel</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.mapParallel</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.mapParallel(fragment, params, list-to-parallelize) yield value - executes fragment in parallel batches with the list segments being assigned to _</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.mapParallel2</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.mapParallel2(fragment, params, list-to-parallelize) yield value - executes fragment in parallel batches with the list segments being assigned to _</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.parallel2</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.doIt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.doIt(fragment, params) yield value - executes writing fragment with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runTimeboxed</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runTimeboxed('cypherStatement',{params}, timeout) - abort statement after timeout ms if not finished</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.when</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.when(condition, ifQuery, elseQuery:'', params:{}) yield value - based on the conditional, executes read-only ifQuery or elseQuery with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.do.when</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.do.when(condition, ifQuery, elseQuery:'', params:{}) yield value - based on the conditional, executes writing ifQuery or elseQuery with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.case</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.case([condition, query, condition, query, &#8230;&#8203;], elseQuery:'', params:{}) yield value - given a list of conditional / read-only query pairs, executes the query associated with the first conditional evaluating to true (or the else query if none are true) with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.do.case</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.do.case([condition, query, condition, query, &#8230;&#8203;], elseQuery:'', params:{}) yield value - given a list of conditional / writing query pairs, executes the query associated with the first conditional evaluating to true (or the else query if none are true) with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.gephi.add</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.gephi.add(url-or-key, workspace, data, weightproperty) | streams passed in data to Gephi</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.add</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.add(node/relatonship,propertyName,number) Sums the property&#8217;s value with the 'number' value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.subtract</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.subtract(node/relatonship,propertyName,number) Subtracts the 'number' value to the property&#8217;s value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.concat</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.concat(node/relatonship,propertyName,string) Concats the property&#8217;s value with the 'string' value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.insert</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.insert(node/relatonship,propertyName,position,value) insert a value into the property&#8217;s array value at 'position'</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.remove</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.remove(node/relatonship,propertyName,position) remove the element at position 'position'</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.update</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.atomic.update(node/relatonship,propertyName,updateOperation) update a property&#8217;s value with a cypher operation (ex. "n.prop1+n.prop2")</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.regr</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.regr(label, propertyY, propertyX) - It calculates the coefficient of determination (R-squared) for the values of propertyY and propertyX in the provided label</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.get</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.get(host-or-port,db-or-null,collection-or-null,query-or-null,[compatibleValues=true|false]) yield value - perform a find operation on mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.count</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.count(host-or-port,db-or-null,collection-or-null,query-or-null) yield value - perform a find operation on mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.first</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.first(host-or-port,db-or-null,collection-or-null,query-or-null,[compatibleValues=true|false]) yield value - perform a first operation on mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.find</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.find(host-or-port,db-or-null,collection-or-null,query-or-null,projection-or-null,sort-or-null,[compatibleValues=true|false]) yield value - perform a find,project,sort operation on mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.insert</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.insert(host-or-port,db-or-null,collection-or-null,list-of-maps) - inserts the given documents into the mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.delete</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.delete(host-or-port,db-or-null,collection-or-null,list-of-maps) - inserts the given documents into the mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.update</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.mongodb.update(host-or-port,db-or-null,collection-or-null,list-of-maps) - inserts the given documents into the mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.search.nodeAllReduced</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Do a parallel search over multiple indexes returning a reduced representation of the nodes found: node id, labels and the searched property. apoc.search.nodeShortAll( map of label and properties which will be searched upon, operator: EXACT / CONTAINS / STARTS WITH | ENDS WITH / = / &lt;&gt; / &lt; / &gt; &#8230;&#8203;, value ). All 'hits' are returned.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.search.nodeReduced</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Do a parallel search over multiple indexes returning a reduced representation of the nodes found: node id, labels and the searched properties. apoc.search.nodeReduced( map of label and properties which will be searched upon, operator: EXACT | CONTAINS | STARTS WITH | ENDS WITH, searchValue ). Multiple search results for the same node are merged into one record.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.search.multiSearchReduced</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Do a parallel search over multiple indexes returning a reduced representation of the nodes found: node id, labels and the searched properties. apoc.search.multiSearchReduced( map of label and properties which will be searched upon, operator: EXACT | CONTAINS | STARTS WITH | ENDS WITH, searchValue ). Multiple search results for the same node are merged into one record.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.search.nodeAll</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Do a parallel search over multiple indexes returning nodes. usage apoc.search.nodeAll( map of label and properties which will be searched upon, operator: EXACT | CONTAINS | STARTS WITH | ENDS WITH, searchValue ) returns all the Nodes found in the different searches.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.search.node</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Do a parallel search over multiple indexes returning nodes. usage apoc.search.node( map of label and properties which will be searched upon, operator: EXACT | CONTAINS | STARTS WITH | ENDS WITH, searchValue ) returns all the DISTINCT Nodes found in the different searches.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.assert</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.assert({indexLabel:[indexKeys], &#8230;&#8203;}, {constraintLabel:[constraintKeys], &#8230;&#8203;}, dropExisting : true) yield label, key, unique, action - drops all other existing indexes and constraints when <code>dropExisting</code> is <code>true</code> (default is <code>true</code>), and asserts that at the end of the operation the given indexes and unique constraints are there, each label:key pair is considered one constraint/label</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.nodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.schema.nodes() yield name, label, properties, status, type</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.relationships</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.schema.relationships() yield name, startLabel, type, endLabel, properties, status</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.zipToRows</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.zipToRows(list1,list2) - creates pairs like zip but emits one row per pair</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.partition</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.partition(list,batchSize)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.split</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.split(list,value) | splits collection on given values rows of lists, value itself will not be part of resulting lists</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.csv</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.csv('url',{config}) YIELD lineNo, list, map - load CSV fom URL as stream of values,
 config contains any of: {skip:1,limit:5,header:false,sep:'TAB',ignore:['tmp'],arraySep:';',mapping:{years:{type:'int',arraySep:'-',array:false,name:'age',ignore:false}}</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.ldap</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.ldap("key" or {connectionMap},{searchMap}) Load entries from an ldap source (yield entry)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.driver</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.driver('org.apache.derby.jdbc.EmbeddedDriver') register JDBC driver of source database</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.jdbc</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.jdbc('key or url','table or statement') YIELD row - load from relational database, from a full table or a sql statement</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.jdbcParams</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">deprecated - please use: apoc.load.jdbc('key or url','statement',[params]) YIELD row - load from relational database, from a sql statement with parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.jdbcUpdate</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.jdbcUpdate('key or url','statement',[params]) YIELD row - update relational database, from a SQL statement with optional parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.jsonArray</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.jsonArray('url') YIELD value - load array from JSON URL (e.g. web-api) to import JSON as stream of values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.json</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.json('url',path, config) YIELD value -  import JSON as stream of values if the JSON was an array or a single value if it was a map</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.jsonParams</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.jsonParams('url',{header:value},payload, config) YIELD value - load from JSON URL (e.g. web-api) while sending headers / payload to import JSON as stream of values if the JSON was an array or a single value if it was a map</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.xml</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.xml('http://example.com/test.xml', 'xPath',config, false) YIELD value as doc CREATE (p:Person) SET p.name = doc.name load from XML URL (e.g. web-api) to import XML as single nested map with attributes and _type, _text and _childrenx fields.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.xmlSimple</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.xmlSimple('http://example.com/test.xml') YIELD value as doc CREATE (p:Person) SET p.name = doc.name load from XML URL (e.g. web-api) to import XML as single nested map with attributes and _type, _text and _children fields. This method does intentionally not work with XML mixed content.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.generate.ba</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.generate.ba(noNodes, edgesPerNode, label, type) - generates a random graph according to the Barabasi-Albert model</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.generate.ws</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.generate.ws(noNodes, degree, beta, label, type) - generates a random graph according to the Watts-Strogatz model</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.generate.er</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.generate.er(noNodes, noEdges, label, type) - generates a random graph according to the Erdos-Renyi model</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.generate.complete</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.generate.complete(noNodes, label, type) - generates a random complete graph</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.generate.simple</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.generate.simple(degrees, label, type) - generates a simple random graph according to the given degree distribution</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addAllNodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addAllNodes('name',{label1:['prop1',&#8230;&#8203;],&#8230;&#8203;}, {options}) YIELD type, name, config - create a free text search index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addAllNodesExtended</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addAllNodesExtended('name',{label1:['prop1',&#8230;&#8203;],&#8230;&#8203;}, {options}) YIELD type, name, config - create a free text search index with special options</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.search</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.search('name', 'query', [maxNumberOfResults]) YIELD node, weight - search for nodes in the free text index matching the given query</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.related</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.relatedNodes([nodes],label,key,'&lt;TYPE'/'TYPE&gt;'/'TYPE',limit) yield node - schema range scan which keeps index order and adds limit and checks opposite node of relationship against the given set of nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.orderedRange</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.orderedRange(label,key,min,max,sort-relevance,limit) yield node - schema range scan which keeps index order and adds limit, values can be null, boundaries are inclusive</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.orderedByText</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.orderedByText(label,key,operator,value,sort-relevance,limit) yield node - schema string search which keeps index order and adds limit, operator is 'STARTS WITH' or 'CONTAINS'</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.properties.distinct</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.properties.distinct(label, key) - quickly returns all distinct values for a given key</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.properties.distinctCount</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.properties.distinctCount([label], [key]) YIELD label, key, value, count - quickly returns all distinct values and counts for a given key</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.nodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.nodes('Label','prop:value*') YIELD node - lucene query on node index with the given label name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.forNodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.forNodes('name',{config}) YIELD type,name,config - gets or creates node index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.forRelationships</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.forRelationships('name',{config}) YIELD type,name,config - gets or creates relationship index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.remove</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.remove('name') YIELD type,name,config - removes an manual index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.list</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.list() - YIELD type,name,config - lists all manual indexes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.relationships</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.relationships('TYPE','prop:value*') YIELD rel - lucene query on relationship index with the given type name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.between</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.between(node1,'TYPE',node2,'prop:value*') YIELD rel - lucene query on relationship index with the given type name bound by either or both sides (each node parameter can be null)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.out</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">out(node,'TYPE','prop:value*') YIELD node - lucene query on relationship index with the given type name for <strong>outgoing</strong> relationship of the given node, <strong>returns end-nodes</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.in</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.in(node,'TYPE','prop:value*') YIELD node lucene query on relationship index with the given type name for <strong>incoming</strong> relationship of the given node, <strong>returns start-nodes</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addNode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addNode(node,['prop1',&#8230;&#8203;]) add node to an index for each label it has</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addNodeByLabel</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addNodeByLabel(node,'Label',['prop1',&#8230;&#8203;]) add node to an index for the given label</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addNodeByName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addNodeByName('name',node,['prop1',&#8230;&#8203;]) add node to an index for the given name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addRelationship</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addRelationship(rel,['prop1',&#8230;&#8203;]) add relationship to an index for its type</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addRelationshipByName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addRelationshipByName('name',rel,['prop1',&#8230;&#8203;]) add relationship to an index for the given name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.removeNodeByName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.removeNodeByName('name',node) remove node from an index for the given name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.removeRelationshipByName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.removeRelationshipByName('name',rel) remove relationship from an index for the given name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.log.error</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.log.error(message, params) - logs error message</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.log.warn</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.log.warn(message, params) - logs warn message</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.log.info</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.log.info(message, params) - logs info message</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.log.debug</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.log.debug(message, params) - logs debug message</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.phonetic</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.phonetic(value) yield value - Compute the US_ENGLISH phonetic soundex encoding of all words of the text value which can be a single string or a list of strings</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.phoneticDelta</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.phoneticDelta(text1, text2) yield phonetic1, phonetic2, delta - Compute the US_ENGLISH soundex character difference between two given strings</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.stats</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.stats(host-url-Key) - elastic search statistics</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.get</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.get(host-or-port,index-or-null,type-or-null,id-or-null,query-or-null,payload-or-null) yield value - perform a GET operation on elastic search</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.query</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.query(host-or-port,index-or-null,type-or-null,query-or-null,payload-or-null) yield value - perform a SEARCH operation on elastic search</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.getRaw</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.getRaw(host-or-port,path,payload-or-null) yield value - perform a raw GET operation on elastic search</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.postRaw</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.postRaw(host-or-port,path,payload-or-null) yield value - perform a raw POST operation on elastic search</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.post</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.post(host-or-port,index-or-null,type-or-null,query-or-null,payload-or-null) yield value - perform a POST operation on elastic search</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.put</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.put(host-or-port,index-or-null,type-or-null,id-or-null,query-or-null,payload-or-null) yield value - perform a PUT operation on elastic search</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypher.all</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypher.all(file,config) - exports whole database incl. indexes as cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypher.data</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypher.data(nodes,rels,file,config) - exports given nodes and relationships incl. indexes as cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypher.graph</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypher.graph(graph,file,config) - exports given graph object incl. indexes as cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypher.query</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypher.query(query,file,config) - exports nodes and relationships from the cypher statement incl. indexes as cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypher.schema</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypher.schema(file,config) - exports all schema indexes and constraints to cypher</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.csv.all</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.csv.data</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.csv.graph</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.csv.query</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypherAll</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypherAll(file,config) - exports whole database incl. indexes as cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypherData</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypherData(nodes,rels,file,config) - exports given nodes and relationships incl. indexes as cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypherGraph</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypherGraph(graph,file,config) - exports given graph object incl. indexes as cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypherQuery</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.cypherQuery(query,file,config) - exports nodes and relationships from the cypher statement incl. indexes as cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.import.graphml</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.import.graphml(file,config) - imports graphml file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.graphml.all</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.graphml.all(file,config) - exports whole database as graphml to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.graphml.data</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.graphml.data(nodes,rels,file,config) - exports given nodes and relationships as graphml to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.graphml.graph</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.graphml.graph(graph,file,config) - exports given graph object as graphml to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.graphml.query</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.export.graphml.query(query,file,config) - exports nodes and relationships from the cypher statement as graphml to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.spatial.sortByDistance</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.spatial.sortPathsByDistance(List&lt;Path&gt;) sort the given paths based on the geo informations (lat/long) in ascending order</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.spatial.geocodeOnce</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.spatial.geocodeOnce('address') YIELD location, latitude, longitude, description, osmData - look up geographic location of address from openstreetmap geocoding service</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.spatial.geocode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.spatial.geocode('address') YIELD location, latitude, longitude, description, osmData - look up geographic location of address from openstreetmap geocoding service</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.node</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.node(['Label'], {key:value,&#8230;&#8203;}) - create node with dynamic labels</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.addLabels</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.addLabels( [node,id,ids,nodes], ['Label',&#8230;&#8203;]) - adds the given labels to the node or nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.setProperty</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.setProperty( [node,id,ids,nodes], key, value) - sets the given property on the node(s)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.setRelProperty</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.setRelProperty( [rel,id,ids,rels], key, value) - sets the given property on the relationship(s)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.setProperties</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.setProperties( [node,id,ids,nodes], [keys], [values]) - sets the given property on the nodes(s)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.setRelProperties</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.setRelProperties( [rel,id,ids,rels], [keys], [values]) - sets the given property on the relationship(s)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.setLabels</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.setLabels( [node,id,ids,nodes], ['Label',&#8230;&#8203;]) - sets the given labels, non matching labels are removed on the node or nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.removeLabels</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.removeLabels( [node,id,ids,nodes], ['Label',&#8230;&#8203;]) - removes the given labels from the node or nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.nodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.nodes(['Label'], [{key:value,&#8230;&#8203;}]) create multiple nodes with dynamic labels</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.relationship</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.relationship(person1,'KNOWS',{key:value,&#8230;&#8203;}, person2) create relationship with dynamic rel-type</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vNode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vNode(['Label'], {key:value,&#8230;&#8203;}) returns a virtual node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vNodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vNodes(['Label'], [{key:value,&#8230;&#8203;}]) returns virtual nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vRelationship</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vRelationship(nodeFrom,'KNOWS',{key:value,&#8230;&#8203;}, nodeTo) returns a virtual relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vPattern</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vPattern({_labels:['LabelA'],key:value},'KNOWS',{key:value,&#8230;&#8203;}, {_labels:['LabelB'],key:value}) returns a virtual pattern</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vPatternFull</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vPatternFull(['LabelA'],{key:value},'KNOWS',{key:value,&#8230;&#8203;},['LabelB'],{key:value}) returns a virtual pattern</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.uuids</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.uuids(count) yield uuid - creates 'count' UUIDs</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.warmup.run</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.warmup.run() - quickly loads all nodes and rels into memory by skipping one page at a time</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.stats.degrees</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.help</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Provides descriptions of available procedures. To narrow the results, supply a search string. To also search in the description text, append + to the end of the search string.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.rename.label</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.rename.label(oldLabel, newLabel, [nodes]) | rename a label from 'oldLabel' to 'newLabel' for all nodes. If 'nodes' is provided renaming is applied to this set only</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.rename.type</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.rename.type(oldType, newType, [rels]) | rename all relationships with type 'oldType' to 'newType'. If 'rels' is provided renaming is applied to this set only</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.rename.nodeProperty</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.rename.nodeProperty(oldName, newName, [nodes]) | rename all node&#8217;s property from 'oldName' to 'newName'. If 'nodes' is provided renaming is applied to this set only</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.rename.typeProperty</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.rename.typeProperty(oldName, newName, [rels]) | rename all relationship&#8217;s property from 'oldName' to 'newName'. If 'rels' is provided renaming is applied to this set only</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.extractNode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.extractNode([rel1,rel2,&#8230;&#8203;], [labels],'OUT','IN') extract node from relationships</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.collapseNode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.collapseNode([node1,node2],'TYPE') collapse node to relationship, node with one rel becomes self-relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.cloneNodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.cloneNodes([node1,node2,&#8230;&#8203;]) clone nodes with their labels and properties</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.cloneNodesWithRelationships</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.cloneNodesWithRelationships([node1,node2,&#8230;&#8203;]) clone nodes with their labels, properties and relationships</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.mergeNodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.mergeNodes([node1,node2]) merge nodes onto first in list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.mergeRelationships</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.mergeRelationships([rel1,rel2]) merge relationships onto first in list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.setType</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.setType(rel, 'NEW-TYPE') change relationship-type</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.to</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.to(rel, endNode) redirect relationship to use new end-node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.invert</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.invert(rel) inverts relationship direction</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.from</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.from(rel, startNode) redirect relationship to use new start-node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.normalizeAsBoolean</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.normalizeAsBoolean(entity, propertyKey, true_values, false_values) normalize/convert a property to be boolean</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.categorize</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.refactor.categorize(sourceKey, type, outgoing, label, targetKey, copiedKeys, batchSize) turn each unique propertyKey into a category node and connect to it</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.setJsonProperty</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.setJsonProperty(node,key,complexValue) - sets value serialized to JSON as property with the given name on the node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toTree</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toTree([paths]) creates a stream of nested documents representing the at least one root of these paths</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.get</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.get(nodes, bucket, documentId) yield id, expiry, cas, mutationToken, content - retrieves a couchbase json document by its unique ID.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.exists</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.exists(nodes, bucket, documentId) yield value - check whether a couchbase json document with the given ID does exist.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.insert</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.insert(nodes, bucket, documentId, jsonDocument) yield id, expiry, cas, mutationToken, content - insert a couchbase json document with its unique ID.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.upsert</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.upsert(nodes, bucket, documentId, jsonDocument) yield id, expiry, cas, mutationToken, content - insert or overwrite a couchbase json document with its unique ID.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.append</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.append(nodes, bucket, documentId, jsonDocument) yield id, expiry, cas, mutationToken, content - append a couchbase json document to an existing one.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.prepend</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.prepend(nodes, bucket, documentId, jsonDocument) yield id, expiry, cas, mutationToken, content - prepend a couchbase json document to an existing one.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.remove</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.remove(nodes, bucket, documentId) yield id, expiry, cas, mutationToken, content - remove the couchbase json document identified by its unique ID.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.replace</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.replace(nodes, bucket, documentId, jsonDocument) yield id, expiry, cas, mutationToken, content - replace the content of the couchbase json document identified by its unique ID.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.query</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.query(nodes, bucket, statement) yield queryResult - executes a plain un-parameterized N1QL statement.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.posParamsQuery</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.posParamsQuery(nodes, bucket, statement, params) yield queryResult - executes a N1QL statement with positional parameters.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.namedParamsQuery</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.couchbase.namedParamsQuery(nodes, bucket, statement, paramNames, paramValues) yield queryResult - executes a N1QL statement with named parameters.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.trigger.nodesByLabel</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.trigger.propertiesByKey</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.sha1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.sha1([values]) | computes the sha1 of the concatenation of all string values of the list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.sha256</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.sha256([values]) | computes the sha256 of the concatenation of all string values of the list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.sha384</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.sha384([values]) | computes the sha384 of the concatenation of all string values of the list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.sha512</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.sha512([values]) | computes the sha512 of the concatenation of all string values of the list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.md5</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.util.md5([values]) | computes the md5 of the concatenation of all string values of the list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.node.relationship.exists</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.node.relationship.exists(node, [rel-direction-pattern]) - yields true effectively when the node has the relationships of the pattern</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.connected</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.connected(start, end, [rel-direction-pattern]) - yields true effectively when the node is connected to the other node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.node.degree</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.node.degree(node, [rel-direction-pattern]) - yields degree effectively when the node has the relationships of the pattern</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.node.relationship.types</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.node.relationship.types(node, [rel-direction-pattern]) - yields distinct relationship-types</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.isDense</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.nodes.isDense(node) - returns true if it is a dense node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.toYears</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">toYears(timestap) or toYears(date[,format]) converts timestamp into floating point years</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.fields</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.fields('2012-12-23',('yyyy-MM-dd')) - return columns and a map representation of date parsed with the given format with entries for years,months,weekdays,days,hours,minutes,seconds,zoneid</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.currentTimestamp</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.currentTimestamp() - returns System.currentTimeMillis()</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.format</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.format(12345,('ms|s|m|h|d'),('yyyy-MM-dd HH:mm:ss zzz'),('TZ')) get string representation of time value optionally using the specified unit (default ms) using specified format (default ISO) and specified time zone (default current TZ)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.parse</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.parse('2012-12-23','ms|s|m|h|d','yyyy-MM-dd') parse date string using the specified format into the specified time unit</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.systemTimezone</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.systemTimezone() returns the system timezone display name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.convert</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.convert(12345, 'ms', 'd') convert a timestamp in one time unit into one of a different time unit</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.add</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.date.add(12345, 'ms', -365, 'd') given a timestamp in one time unit, adds a value of the specified time unit</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.cosineSimilarity</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.cosineSimilarity([vector1], [vector2]) given two collection vectors, calculate cosine similarity</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.euclideanDistance</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.euclideanDistance([vector1], [vector2]) given two collection vectors, calculate the euclidean distance (square root of the sum of the squared differences)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.euclideanSimilarity</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.algo.euclideanSimilarity([vector1], [vector2]) given two collection vectors, calculate similarity based on euclidean distance</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.type</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.type(value) - type name of a value (INTEGER,FLOAT,STRING,BOOLEAN,RELATIONSHIP,NODE,PATH,NULL,UNKNOWN,MAP,LIST)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.typeName</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.typeName(value) - type name of a value (INTEGER,FLOAT,STRING,BOOLEAN,RELATIONSHIP,NODE,PATH,NULL,UNKNOWN,MAP,LIST)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.types</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.types(node-relationship-map)  - returns a map of keys to types</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.isType</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.meta.isType(value,type) - returns a row if type name matches none if not (INTEGER,FLOAT,STRING,BOOLEAN,RELATIONSHIP,NODE,PATH,NULL,UNKNOWN,MAP,LIST)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runFirstColumn</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runFirstColumn(statement, params, expectMultipleValues) - executes statement with given parameters, returns first column only, if expectMultipleValues is true will collect results into an array</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.round</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.round(value,[prec],mode=[CEILING,FLOOR,UP,DOWN,HALF_EVEN,HALF_DOWN,HALF_UP,DOWN,UNNECESSARY])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.maxLong</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.maxLong() | return the maximum value a long can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.minLong</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.minLong() | return the minimum value a long can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.maxDouble</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.maxDouble() | return the largest positive finite value of type double</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.minDouble</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.minDouble() | return the smallest positive nonzero value of type double</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.maxInt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.maxInt() | return the maximum value an int can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.minInt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.minInt() | return the minimum value an int can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.maxByte</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.maxByte() | return the maximum value an byte can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.minByte</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.math.minByte() | return the minimum value an byte can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.format</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.format(number)  | format a long or double using the default system pattern and language to produce a string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.parseInt</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.parseInt(text)  | parse a text using the default system pattern and language to produce a long</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.parseFloat</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.parseFloat(text)  | parse a text using the default system pattern and language to produce a double</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.exact.add</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.exact.sub</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.exact.mul</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.exact.div</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.exact.toInteger</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.exact.toFloat</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.number.exact.toExact</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.node.indexExists</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">RETURN apoc.schema.node.indexExists(labelName, propertyNames)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.node.constraintExists</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">RETURN apoc.schema.node.constraintExists(labelName, propertyNames)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.relationship.constraintExists</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">RETURN apoc.schema.relationship.constraintExists(type, propertyNames)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.zip</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.zip([list1],[list2])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.pairs</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.pairs([1,2,3]) returns [1,2],[2,3],[3,null]</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.pairsMin</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.pairsMin([1,2,3]) returns [1,2],[2,3]</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sum</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sum([0.5,1,2.3])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.avg</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.avg([0.5,1,2.3])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.min</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.min([0.5,1,2.3])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.max</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.max([0.5,1,2.3])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.contains</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.contains(coll, value) optimized contains operation (using a HashSet) (returns single row or not)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.indexOf</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.indexOf(coll, value) | position of value in the list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.containsAll</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.containsAll(coll, values) optimized contains-all operation (using a HashSet) (returns single row or not)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.containsSorted</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.containsSorted(coll, value) optimized contains on a sorted list operation (Collections.binarySearch) (returns single row or not)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.containsAllSorted</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.containsAllSorted(coll, value) optimized contains-all on a sorted list operation (Collections.binarySearch) (returns single row or not)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.toSet</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.toSet([list]) returns a unique list backed by a set</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sumLongs</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sumLongs([1,3,3])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sort</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sort(coll) sort on Collections</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sortNodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sortNodes([nodes], 'name') sort nodes by property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sortMaps</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sortMaps([maps], 'name') - sort maps by property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.union</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.union(first, second) - creates the distinct union of the 2 lists</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.subtract</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.subtract(first, second) - returns unique set of first list with all elements of second list removed</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.removeAll</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.removeAll(first, second) - returns first list with all elements of second list removed</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.intersection</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.intersection(first, second) - returns the unique intersection of the two lists</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.disjunction</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.disjunction(first, second) - returns the disjunct set of the two lists</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.unionAll</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.unionAll(first, second) - creates the full union with duplicates of the two lists</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.shuffle</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.shuffle(coll) - returns the shuffled list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.randomItem</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.randomItem(coll)- returns a random item from the list, or null on an empty or null list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.randomItems</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.randomItems(coll, itemCount, allowRepick: false) - returns a list of itemCount random items from the original list, optionally allowing picked elements to be picked again</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.containsDuplicates</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.containsDuplicates(coll) - returns true if a collection contains duplicate elements</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.duplicates</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.duplicates(coll) - returns a list of duplicate items in the collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.duplicatesWithCount</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.duplicatesWithCount(coll) - returns a list of duplicate items in the collection and their count, keyed by <code>item</code> and <code>count</code> (e.g., <code>[{item: xyz, count:2}, {item:zyx, count:5}]</code>)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.occurrences</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.occurrences(coll, item) - returns the count of the given item in the collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.flatten</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.flatten(coll) - flattens nested list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.reverse</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.reverse(coll) - returns reversed list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sortMulti</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.coll.sortMulti(coll, ['^name','age'],[limit],[skip]) - sort list of maps by several sort fields (ascending with ^ prefix) and optionally applies limit and skip</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.groupBy</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.groupBy([maps/nodes/relationships],'key') yield value - creates a map of the list keyed by the given property, with single values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.groupByMulti</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.groupByMulti([maps/nodes/relationships],'key') yield value - creates a map of the list keyed by the given property, with list values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.fromNodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.fromNodes(label, property)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.fromPairs</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.fromPairs([[key,value],[key2,value2],&#8230;&#8203;])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.fromLists</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.fromLists([keys],[values])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.fromValues</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.fromValues([key1,value1,key2,value2,&#8230;&#8203;])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.merge</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.merge(first,second) - merges two maps</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.mergeList</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.mergeList([{maps}]) yield value - merges all maps in the list into one</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.setKey</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.setKey(map,key,value)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.setEntry</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.setEntry(map,key,value)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.setPairs</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.setPairs(map,[[key1,value1],[key2,value2])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.setLists</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.setLists(map,[keys],[values])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.setValues</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.setValues(map,[key1,value1,key2,value2])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.removeKey</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.removeKey(map,key)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.removeKeys</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.removeKeys(map,keys)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.clean</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.clean(map,[skip,keys],[skip,values]) yield map removes the keys and values contained in those lists, good for data cleaning from CSV/JSON</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.updateTree</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.updateTree(tree,key,<a id="value"></a>) returns map - adds the {data} map on each level of the nested tree, where the key-value pairs match</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.flatten</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.flatten(map) yield map - flattens nested items in map using dot notation</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.sortedProperties</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.map.sortedProperties(map, ignoreCase:true) - returns a list of key/value list pairs, with pairs sorted by keys alphabetically, with optional case sensitivity</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.version</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">RETURN apoc.version() | return the current APOC installed version</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.scoring.existence</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.scoring.existence(5, true) returns the provided score if true, 0 if false</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.scoring.pareto</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.scoring.pareto(10, 20, 100, 11) applies a Pareto scoring function over the inputs</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.replace</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.replace(text, regex, replacement) - replace each substring of the given string that matches the given regular expression with the given replacement.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.regreplace</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.regreplace(text, regex, replacement) - replace each substring of the given string that matches the given regular expression with the given replacement.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.split</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.split(text, regex, limit) - splits the given text around matches of the given regex.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.regexGroups</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.regexGroups(text, regex) - return all matching groups of the regex on the given text.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.join</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.join(['text1','text2',&#8230;&#8203;], delimiter) - join the given strings with the given delimiter.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.clean</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.clean(text) - strip the given string of everything except alpha numeric characters and convert it to lower case.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.compareCleaned</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.compareCleaned(text1, text2) - compare the given strings stripped of everything except alpha numeric characters converted to lower case.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.distance</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.distance(text1, text2) - compare the given strings with the StringUtils.distance(text1, text2) method</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.fuzzyMatch</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.fuzzyMatch(text1, text2) - check if 2 words can be matched in a fuzzy way. Depending on the length of the String it will allow more characters that needs to be editted to match the second String.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.urlencode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.urlencode(text) - return the urlencoded text</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.urldecode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.urldecode(text) - return the urldecoded text</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.lpad</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.lpad(text,count,delim) YIELD value - left pad the string to the given width</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.rpad</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.rpad(text,count,delim) YIELD value - right pad the string to the given width</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.format</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.format(text,[params]) - sprintf format the string with the params given</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.slug</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.slug(text, delim) - slug the text with the given delimiter</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.random</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.random(length, valid) YIELD value - generate a random string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.capitalize</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.capitalize(text) YIELD value - capitalise the first letter of the word</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.capitalizeAll</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.capitalizeAll(text) YIELD value - capitalise the first letter of every word in the text</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.decapitalize</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.decapitalize(text) YIELD value - decapitalize the first letter of the word</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.decapitalizeAll</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.decapitalizeAll(text) YIELD value - decapitalize the first letter of all words</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.swapCase</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.swapCase(text) YIELD value - Swap the case of a string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.camelCase</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.camelCase(text) YIELD value - Convert a string to camelCase</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.upperCamelCase</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.upperCamelCase(text) YIELD value - Convert a string to camelCase</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.snakeCase</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.snakeCase(text) YIELD value - Convert a string to snake-case</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.toUpperCase</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.toUpperCase(text) YIELD value - Convert a string to UPPER_CASE</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.base64Encode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.base64Encode(text) YIELD value - Encode a string with Base64</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.base64Decode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.base64Decode(text) YIELD value - Decode Base64 encoded string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bitwise.op</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bitwise.op(60,'|',13) bitwise operations a &amp; b, a | b, a ^ b, ~a, a &gt;&gt; b, a &gt;&gt;&gt; b, a &lt;&lt; b. returns the result of the bitwise operation</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.data.domain</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.data.domain('url_or_email_address') YIELD domain - extract the domain name from a url or an email address. If nothing was found, yield null.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vNode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vNode(['Label'], {key:value,&#8230;&#8203;}) returns a virtual node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vRelationship</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.vRelationship(nodeFrom,'KNOWS',{key:value,&#8230;&#8203;}, nodeTo) returns a virtual relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.uuid</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.create.uuid() - creates an UUID</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.json.path</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.json.path('{json}','json-path')</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toJson</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toJson([1,2,3]) or toJson({a:42,b:"foo",c:[1,2,3]})</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.getJsonProperty</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.getJsonProperty(node,key[,'json-path']) - converts serialized JSON in property back to original object</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.getJsonPropertyMap</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.getJsonPropertyMap(node,key[,'json-path']) - converts serialized JSON in property back to map</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.fromJsonMap</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.fromJsonMap('{"a":42,"b":"foo","c":[1,2,3]}'[,'json-path'])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.fromJsonList</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.fromJsonList('[1,2,3]'[,'json-path'])</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toSortedJsonMap</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toSortedJsonMap(node|map, ignoreCase:true) - returns a JSON map with keys sorted alphabetically, with optional case sensitivity</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toMap</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toMap(value) | tries it&#8217;s best to convert the value to a map</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toString</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toString(value) | tries it&#8217;s best to convert the value to a string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toList</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toList(value) | tries it&#8217;s best to convert the value to a list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toBoolean</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toBoolean(value) | tries it&#8217;s best to convert the value to a boolean</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toNode</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toNode(value) | tries it&#8217;s best to convert the value to a node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toRelationship</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toRelationship(value) | tries it&#8217;s best to convert the value to a relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toSet</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toSet(value) | tries it&#8217;s best to convert the value to a set</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toIntList</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toIntList(value) | tries it&#8217;s best to convert the value to a list of integers</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toStringList</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toStringList(value) | tries it&#8217;s best to convert the value to a list of strings</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toBooleanList</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toBooleanList(value) | tries it&#8217;s best to convert the value to a list of booleans</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toNodeList</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toNodeList(value) | tries it&#8217;s best to convert the value to a list of nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toRelationshipList</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.convert.toRelationshipList(value) | tries it&#8217;s best to convert the value to a list of relationships</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect1">
<h2 id="_user_defined_functions"><a class="link" href="#_user_defined_functions">User Defined Functions</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Introduced in Neo4j 3.1.0-M10</p>
</div>
<div class="paragraph">
<p>Neo4j 3.1 brings some really neat improvements in Cypher alongside other cool features</p>
</div>
<div class="paragraph">
<p>If you used or wrote procedures in the past, you most probably came across instances where it felt quite unwieldy to call a procedure just to compute something, convert a value or provide a boolean decision.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (v:Value {id:{id}, data:{data}})
WITH v
CALL apoc.date.format(timestamp(), "ms") YIELD value as created
SET v.created = created</code></pre>
</div>
</div>
<div class="paragraph">
<p>You&#8217;d rather write it as a function:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (v:Value {id:{id}, data:{data}, created: apoc.date.format(timestamp()) })</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now in 3.1 that&#8217;s possible, and you can also leave off the <code>"ms"</code> and use a single function name, because the <code>unit</code> and <code>format</code> parameters have a default value.</p>
</div>
<div class="paragraph">
<p>Functions are more limited than procedures: they can’t execute writes or schema operations and are expected to return a single value, not a stream of values.
But this makes it also easier to write and use them.</p>
</div>
<div class="paragraph">
<p>By having information about their types, the Cypher Compiler can also check for applicability.</p>
</div>
<div class="paragraph">
<p>The signature of the procedure above changed from:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@Procedure("apoc.date.format")
public Stream&lt;StringResult&gt; formatDefault(@Name("time") long time, @Name("unit") String unit) {
   return Stream.of(format(time, unit, DEFAULT_FORMAT));
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>to the much simpler function signature (ignoring the parameter name and value annotations):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@UserFunction("apoc.date.format")
public String format(@Name("time") long time,
                     @Name(value="unit", defaultValue="ms") String unit,
                     @Name(value="format", defaultValue=DEFAULT_FORMAT) String format) {
   return getFormatter().format(time, unit, format);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This can then be called in the manner outlined above.</p>
</div>
<div class="paragraph">
<p>In our APOC procedure library we already converted about <a href="https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/144">50 procedures into functions</a> from the following areas:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 40%;">
<col style="width: 20%;">
<col style="width: 40%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">package</th>
<th class="tableblock halign-left valign-top"># of functions</th>
<th class="tableblock halign-left valign-top">example function</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>date &amp; time conversion</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>3</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.date.parse("time",["unit"],["format"])</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>number conversion</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>3</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.number.parse("number",["format"])</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>general type conversion</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>8</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toMap(value)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>type information and checking</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>4</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.meta.type(value)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>collection and map functions</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>25</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.fromList(["k1",v1,"k2",v2,"k3",v3])</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>JSON conversion</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>4</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toJson(value)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>string functions</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>7</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.join(["s1","s2","s3"],"delim")</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>hash functions</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>2</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.util.md5(value)</code></p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>You can list user defined functions with <code>call dbms.functions()</code></p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/dbms.functions.jpg" alt="dbms.functions">
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_text_and_lookup_indexes"><a class="link" href="#_text_and_lookup_indexes">Text and Lookup Indexes</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_index_queries"><a class="link" href="#_index_queries">Index Queries</a></h3>
<div class="paragraph">
<p>Procedures to add to and query manual indexes</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
Please note that there are (case-sensitive) <a href="http://neo4j.com/docs/developer-manual/current/#cypher-schema">automatic schema indexes</a>, for equality, non-equality, existence, range queries, starts with, ends-with and contains!
</td>
</tr>
</table>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 14.2857%;">
<col style="width: 14.2857%;">
<col style="width: 71.4286%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">type</th>
<th class="tableblock halign-left valign-top">qualified name</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addAllNodes</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addAllNodes('name',{label1:['prop1',&#8230;&#8203;],&#8230;&#8203;}, {options}) YIELD type, name, config - create a free text search index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addAllNodesExtended</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addAllNodesExtended('name',{label1:['prop1',&#8230;&#8203;],&#8230;&#8203;}, {options}) YIELD type, name, config - create a free text search index with special options</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.search</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.search('name', 'query', [maxNumberOfResults]) YIELD node, weight - search for nodes in the free text index matching the given query</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.related</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.relatedNodes([nodes],label,key,'&lt;TYPE'/'TYPE&gt;'/'TYPE',limit) yield node - schema range scan which keeps index order and adds limit and checks opposite node of relationship against the given set of nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.orderedRange</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.orderedRange(label,key,min,max,sort-relevance,limit) yield node - schema range scan which keeps index order and adds limit, values can be null, boundaries are inclusive</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.orderedByText</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.orderedByText(label,key,operator,value,sort-relevance,limit) yield node - schema string search which keeps index order and adds limit, operator is 'STARTS WITH' or 'CONTAINS'</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.schema.properties.distinct</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.properties.distinct(label, key) - quickly returns all distinct values for a given key</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.schema.properties.distinctCount</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.schema.properties.distinctCount([label], [key]) YIELD label, key, value, count - quickly returns all distinct values and counts for a given key</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.nodes</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.nodes('Label','prop:value*') YIELD node - lucene query on node index with the given label name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.forNodes</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.forNodes('name',{config}) YIELD type,name,config - gets or creates node index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.forRelationships</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.forRelationships('name',{config}) YIELD type,name,config - gets or creates relationship index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.remove</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.remove('name') YIELD type,name,config - removes an manual index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.list</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.list() - YIELD type,name,config - lists all manual indexes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.relationships</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.relationships('TYPE','prop:value*') YIELD rel - lucene query on relationship index with the given type name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.between</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.between(node1,'TYPE',node2,'prop:value*') YIELD rel - lucene query on relationship index with the given type name bound by either or both sides (each node parameter can be null)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.out</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">out(node,'TYPE','prop:value*') YIELD node - lucene query on relationship index with the given type name for <strong>outgoing</strong> relationship of the given node, <strong>returns end-nodes</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.in</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.in(node,'TYPE','prop:value*') YIELD node lucene query on relationship index with the given type name for <strong>incoming</strong> relationship of the given node, <strong>returns start-nodes</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addNode</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addNode(node,['prop1',&#8230;&#8203;]) add node to an index for each label it has</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addNodeByLabel</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addNodeByLabel(node,'Label',['prop1',&#8230;&#8203;]) add node to an index for the given label</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addNodeByName</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addNodeByName('name',node,['prop1',&#8230;&#8203;]) add node to an index for the given name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addRelationship</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addRelationship(rel,['prop1',&#8230;&#8203;]) add relationship to an index for its type</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addRelationshipByName</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.addRelationshipByName('name',rel,['prop1',&#8230;&#8203;]) add relationship to an index for the given name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.removeNodeByName</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.removeNodeByName('name',node) remove node from an index for the given name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.removeRelationshipByName</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.removeRelationshipByName('name',rel) remove relationship from an index for the given name</p></td>
</tr>
</tbody>
</table>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.index.nodes-with-score.jpg" alt="apoc.index.nodes with score" width="600">
</div>
</div>
</div>
<div class="sect2">
<h3 id="_index_management"><a class="link" href="#_index_management">Index Management</a></h3>
<div class="listingblock">
<div class="title">Add node to index example</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">match (p:Person) call apoc.index.addNode(p,["name","age"]) RETURN count(*);
// 129s for 1M People
call apoc.index.nodes('Person','name:name100*') YIELD node, weight return * limit 2</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_manual_indexes"><a class="link" href="#_manual_indexes">Manual Indexes</a></h3>
<div class="sect3">
<h4 id="_data_used"><a class="link" href="#_data_used">Data Used</a></h4>
<div class="paragraph">
<p>The below examples use <a href="https://github.com/nicolewhite/neo4j-flights">flight data</a>.</p>
</div>
<div class="paragraph">
<p>Here is a sample subset of the data that can be load to try the procedures:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (slc:Airport {abbr:'SLC', id:14869, name:'SALT LAKE CITY INTERNATIONAL'})
CREATE (oak:Airport {abbr:'OAK', id:13796, name:'METROPOLITAN OAKLAND INTERNATIONAL'})
CREATE (bur:Airport {abbr:'BUR', id:10800, name:'BOB HOPE'})
CREATE (f2:Flight {flight_num:6147, day:2, month:1, weekday:6, year:2016})
CREATE (f9:Flight {flight_num:6147, day:9, month:1, weekday:6, year:2016})
CREATE (f16:Flight {flight_num:6147, day:16, month:1, weekday:6, year:2016})
CREATE (f23:Flight {flight_num:6147, day:23, month:1, weekday:6, year:2016})
CREATE (f30:Flight {flight_num:6147, day:30, month:1, weekday:6, year:2016})
CREATE (f2)-[:DESTINATION {arr_delay:-13, taxi_time:9}]-&gt;(oak)
CREATE (f9)-[:DESTINATION {arr_delay:-8, taxi_time:4}]-&gt;(bur)
CREATE (f16)-[:DESTINATION {arr_delay:-30, taxi_time:4}]-&gt;(slc)
CREATE (f23)-[:DESTINATION {arr_delay:-21, taxi_time:3}]-&gt;(slc)
CREATE (f30)-[:DESTINATION]-&gt;(slc)</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_using_manual_index_on_node_properties"><a class="link" href="#_using_manual_index_on_node_properties">Using Manual Index on Node Properties</a></h4>
<div class="paragraph">
<p>In order to create manual index on a node property, you call <code>apoc.index.addNode</code> with the node, providing the properties to be indexed.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (a:Airport)
CALL apoc.index.addNode(a,['name'])
RETURN count(*)</code></pre>
</div>
</div>
<div class="paragraph">
<p>The statement will create the node index with the <strong>same name as the Label name(s) of the node</strong> in this case <code>Airport</code> and add the node by their properties to the index.</p>
</div>
<div class="paragraph">
<p>Once this has been added check if the node index exists using <code>apoc.index.list</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.list()</code></pre>
</div>
</div>
<div class="paragraph">
<p>Usually <code>apoc.index.addNode</code> would be used as part of node-creation, e.g. during LOAD CSV.
There is also <code>apoc.index.addNodes</code> for adding a list of multiple nodes at once.</p>
</div>
<div class="paragraph">
<p>Once the node index is created we can start using it.</p>
</div>
<div class="paragraph">
<p>Here are some examples:</p>
</div>
<div class="paragraph">
<p>The <code>apoc.index.nodes</code> finds nodes in a manual index using the given lucene query.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
That makes only sense if you combine multiple properties in one lookup or use case insensitive or fuzzy matching full-text queries.
In all other cases the built in schema indexes should be used.
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.nodes('Airport','name:inter*') YIELD node AS airport, weight
RETURN airport.name, weight
LIMIT 10</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
Apoc index queries not only return nodes and relationships but also a weight, which is the score returned from the underlying Lucene index.
The results are also sorted by that score.
That&#8217;s especially helpful for partial and fuzzy text searches.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To remove the node index <code>Airport</code> created, use:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.remove('Airport')</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_add_document_to_index"><a class="link" href="#_add_document_to_index">Add "document" to index</a></h5>
<div class="paragraph">
<p>Instead of the key-value pairs of a node or relationship properties, you can also compute a map containing information and add that to the index.
So you could find a node or relationship by information from it&#8217;s neighbours or relationships.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (company:Company {name:'Neo4j,Inc.'})
CREATE (company)&lt;-[:WORKS_AT {since:2013}]-(:Employee {name:'Mark'})
CREATE (company)&lt;-[:WORKS_AT {since:2014}]-(:Employee {name:'Martin'})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (company:Company)&lt;-[worksAt:WORKS_AT]-(employee)
WITH company, { name: company.name, employees:collect(employee.name),startDates:collect(worksAt.since)} as data
CALL apoc.index.addNodeMap(company, data)
RETURN count(*)</code></pre>
</div>
</div>
<div class="paragraph">
<p>These could be example searches that all return the same result node.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.nodes('Company','name:Ne* AND employees:Ma*')</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.nodes('Company','employees:Ma*')</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.nodes('Company','startDates:[2013 TO 2014]')</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_using_manual_index_on_relationship_properties"><a class="link" href="#_using_manual_index_on_relationship_properties">Using Manual Index on Relationship Properties</a></h4>
<div class="paragraph">
<p>The procedure <code>apoc.index.addRelationship</code> is used to create a manual index on relationship properties.</p>
</div>
<div class="paragraph">
<p>As there are no schema indexes for relationships, these manual indexes can be quite useful.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (:Flight)-[r:DESTINATION]-&gt;(:Airport)
CALL apoc.index.addRelationship(r,['taxi_time'])
RETURN count(*)</code></pre>
</div>
</div>
<div class="paragraph">
<p>The statement will create the relationship index with the <strong>same name as relationship-type</strong>, in this case <code>DESTINATION</code> and add the relationship by its properties to the index.</p>
</div>
<div class="paragraph">
<p>Using <code>apoc.index.relationships</code>, we can find the relationship of type <code>DESTINATION</code> with the property <code>taxi_time</code> of 11 minutes.
We can chose to also return the start and end-node.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.relationships('DESTINATION','taxi_time:11') YIELD rel, start AS flight, end AS airport
RETURN flight_num.flight_num, airport.name;</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
Manual relationship indexed do not only store the relationship by its properties but also the start- and end-node.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>That&#8217;s why we can use that information to subselect relationships not only by property but also by those nodes, which is quite powerful.</p>
</div>
<div class="paragraph">
<p>With <code>apoc.index.in</code> we can pin the node with incoming relationships (end-node) to get the start nodes for all the <code>DESTINATION</code> relationships.
For instance to find all flights arriving in 'SALT LAKE CITY INTERNATIONAL' with a taxi_time of 7 minutes we&#8217;d use:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (a:Airport {name:'SALT LAKE CITY INTERNATIONAL'})
CALL apoc.index.in(a,'DESTINATION','taxi_time:7') YIELD node AS flight
RETURN flight</code></pre>
</div>
</div>
<div class="paragraph">
<p>The opposite is <code>apoc.index.out</code>, which takes and binds end-nodes and returns start-nodes of relationships.</p>
</div>
<div class="paragraph">
<p>Really useful to quickly find a subset of relationships between nodes with many relationships (tens of thousands to millions) is <code>apoc.index.between</code>.
Here you bind both the start and end-node and provide (or not) properties of the relationships.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (f:Flight {flight_num:6147})
MATCH (a:Airport {name:'SALT LAKE CITY INTERNATIONAL'})
CALL apoc.index.between(f,'DESTINATION',a,'taxi_time:7') YIELD rel, weight
RETURN *</code></pre>
</div>
</div>
<div class="paragraph">
<p>To remove the relationship index <code>DESTINATION</code> that was created, use.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.remove('DESTINATION')</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_full_text_search"><a class="link" href="#_full_text_search">Full Text Search</a></h3>
<div class="paragraph">
<p>Indexes are used for finding nodes in the graph that further operations can then continue from.
Just like in a book where you look at the index to find a section that interest you, and then start reading from there.
A full text index allows you to find occurrences of individual words or phrases across all attributes.</p>
</div>
<div class="paragraph">
<p>In order to use the full text search feature, we have to first index our data by specifying all the attributes we want to index.
Here we create a full text index called <code>“locations”</code> (we will use this name when searching in the index) with our data.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
by default these fulltext indexes do not automatically track changes you perform in your graph. See &#8230;&#8203;. for how to enabled automatic index tracking.
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.addAllNodes('locations',{
  Company: ["name", "description"],
  Person:  ["name","address"],
  Address: ["address"]})</code></pre>
</div>
</div>
<div class="paragraph">
<p>Creating the index will take a little while since the procedure has to read through the entire database to create the index.</p>
</div>
<div class="paragraph">
<p>We can now use this index to search for nodes in the database.
The most simple case would be to search across all data for a particular word.</p>
</div>
<div class="paragraph">
<p>It does not matter which property that word exists in, any node that has that word in any of its indexed properties will be found.</p>
</div>
<div class="paragraph">
<p>If you use a name in the call, all occurrences will be found (but limited to 100 results).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.search("locations", 'name')</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_advanced_search"><a class="link" href="#_advanced_search">Advanced Search</a></h4>
<div class="paragraph">
<p>We can further restrict our search to only searching in a particular attribute.
In order to search for a <code>Person</code> with an address in <strong>France</strong>, we use the following.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.search("locations", "Person.address:France")</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now we can search for nodes with a specific property value, and then explore their neighbourhoods visually.</p>
</div>
<div class="paragraph">
<p>But integrating it with an graph query is so much more powerful.</p>
</div>
</div>
<div class="sect3">
<h4 id="_fulltext_and_graph_search"><a class="link" href="#_fulltext_and_graph_search">Fulltext and Graph Search</a></h4>
<div class="paragraph">
<p>We could for instance search for addresses in the database that contain the word "Paris", and then find all companies registered at those addresses:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.search("locations", "Address.address:Paris~") YIELD node AS addr
MATCH (addr)&lt;-[:HAS_ADDRESS]-(company:Company)
RETURN company LIMIT 50</code></pre>
</div>
</div>
<div class="paragraph">
<p>The tilde (~) instructs the index search procedure to do a fuzzy match, allowing us to find "Paris" even if the spelling is slightly off.</p>
</div>
<div class="paragraph">
<p>We might notice that there are addresses that contain the word “Paris” that are not in Paris, France.
For example there might be a Paris Street somewhere.</p>
</div>
<div class="paragraph">
<p>We can further specify that we want the text to contain both the word Paris, and the word France:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.search("locations", "+Address.address:Paris~ +France~")
YIELD node AS addr
MATCH (addr)&lt;-[:HAS_ADDRESS]-(company:Company)
RETURN company LIMIT 50</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_complex_searches"><a class="link" href="#_complex_searches">Complex Searches</a></h4>
<div class="paragraph">
<p>Things start to get interesting when we look at how the different entities in Paris are connected to one another.
We can do that by finding all the entities with addresses in Paris, then creating all pairs of such entities and finding the shortest path between each such pair:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.search("locations", "+Address.address:Paris~ +France~") YIELD node AS addr
MATCH (addr)&lt;-[:HAS_ADDRESS]-(company:Company)
WITH collect(company) AS companies

// create unique pairs
UNWIND companies AS x UNWIND companies AS y
WITH x, y WHERE ID(x) &lt; ID(y)

MATCH path = shortestPath((x)-[*..10]-(y))
RETURN path</code></pre>
</div>
</div>
<div class="paragraph">
<p>For more details on the query syntax used in the second parameter of the <code>search</code> procedure,
please see <a href="http://www.lucenetutorial.com/lucene-query-syntax.html">this Lucene query tutorial</a></p>
</div>
<div class="sect4">
<h5 id="_index_configuration"><a class="link" href="#_index_configuration">Index Configuration</a></h5>
<div class="paragraph">
<p><code>apoc.index.addAllNodes(&lt;name&gt;, &lt;labelPropsMap&gt;, &lt;option&gt;)</code> allows to fine tune your indexes using the options parameter defaulting to an empty map.
All <a href="https://neo4j.com/docs/java-reference/3.1/#indexing-create-advanced">standard options</a> for <a href="https://neo4j.com/docs/java-reference/3.1/#indexing">Neo4j manual indexes</a> are allowed plus apoc specific options:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">name</th>
<th class="tableblock halign-left valign-top">value</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>type</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>fulltext/exact</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>type of the index</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>to_lower_case</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>false/true</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>if terms should be converted to lower case before indexing</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>analyzer</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>classname</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>classname of lucene analyzer to be used for this index</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>similarity</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>classname</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>classname for lucene similarity to be used for this index</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>autoUpdate</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true/false</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>if this index should be tracked for graph updates</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
An index configuration cannot be changed once the index is created.
However subsequent invocations of <code>apoc.index.addAllNodes</code> will delete the index if existing and create it afterwards.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_automatic_index_tracking_for_manual_indexes"><a class="link" href="#_automatic_index_tracking_for_manual_indexes">Automatic Index Tracking for Manual Indexes</a></h4>
<div class="paragraph">
<p>As mentioned above, <code>apoc.index.addAllNodes()</code> populates an fulltext index.
But it does not track changes being made to the graph and reflect these changes to the index.
You would have to rebuild that index regularly yourself.</p>
</div>
<div class="paragraph">
<p>Or alternatively use the automatic index tracking, that keeps the index in sync with your graph changes.
To enable this feature a two step configuration approach is required.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
Please note that there is a performance impact if you enable automatic index tracking.
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="title">in <code>neo4j.conf</code> set</div>
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">apoc.autoIndex.enabled=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>This global setting will initialize a transaction event handler to take care of reflecting changes of any added nodes, deleted nodes, changed properties to the indexes.</p>
</div>
<div class="paragraph">
<p>In addition to enable index tracking globally using <code>apoc.autoIndex.enabled</code> each individual index must be configured as "trackable" by setting <code>autoUpdate:true</code> in the options when initially creating an index:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.addAllNodes('locations',{
  Company: ["name", "description"],
  Person:  ["name","address"],
  Address: ["address"]}, {autoUpdate:true})</code></pre>
</div>
</div>
<div class="paragraph">
<p>By default index tracking is done synchronously.
That means updates to fulltext indexes are part of same transaction as the originating change (e.g. changing a node property).
While this guarantees instant consistency it has an impact on performance.</p>
</div>
<div class="paragraph">
<p>Alternatively, you can decide to perform index updates asynchronously in a separate thread by setting this flag in <code>neo4j.conf</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">apoc.autoIndex.async=true</code></pre>
</div>
</div>
<div class="paragraph">
<p>With this setting enabled, index updates are fed to a buffer queue that is consumed asynchronously using transaction batches.
The batching can be further configured using</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-properties" data-lang="properties">apoc.autoIndex.queue_capacity=100000
apoc.autoIndex.async_rollover_opscount=50000
apoc.autoIndex.async_rollover_millis=5000
apoc.autoIndex.tx_handler_stopwatch=false</code></pre>
</div>
</div>
<div class="paragraph">
<p>The values above are the default setting.
In this example the index updates are consumed in transactions of maximum 50000 operations or 5000 milliseconds - whichever triggers first will cause the index update transaction to be committed and rolled over.</p>
</div>
<div class="paragraph">
<p>If <code>apoc.autoIndex.tx_handler_stopwatch</code> is enabled, the time spent in <code>beforeCommit</code> and <code>afterCommit</code> is traced to <code>debug.log</code>.
Use this setting only for diagnosis.</p>
</div>
<div class="sect4">
<h5 id="_a_worked_example_on_fulltext_index_tracking"><a class="link" href="#_a_worked_example_on_fulltext_index_tracking">A Worked Example on Fulltext Index Tracking</a></h5>
<div class="paragraph">
<p>This section provides a small but still usable example to understand automatic index updates.</p>
</div>
<div class="paragraph">
<p>Make sure <code>apoc.autoIndex.enabled=true</code> is set.
First we create some nodes - note there&#8217;s no index yet.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">UNWIND ["Johnny Walker", "Jim Beam", "Jack Daniels"] as name CREATE (:Person{name:name})</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now we index them:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.addAllNodes('people', { Person:["name"]}, {autoUpdate:true})</code></pre>
</div>
</div>
<div class="paragraph">
<p>Check if we can find "Johnny" - we expect one result.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.search("people", "Johnny") YIELD node, weight
RETURN node.name, weight</code></pre>
</div>
</div>
<div class="paragraph">
<p>Adding some more people - note, we have another "Johnny":</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">UNWIND ["Johnny Rotten", "Axel Rose"] as name CREATE (:Person{name:name})</code></pre>
</div>
</div>
<div class="paragraph">
<p>Again we&#8217;re search for "Johnny", expecting now two of them:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.index.search("people", "Johnny") YIELD node, weight
RETURN node.name, weight</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_utility_functions"><a class="link" href="#_utility_functions">Utility Functions</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_phonetic_text_procedures"><a class="link" href="#_phonetic_text_procedures">Phonetic Text Procedures</a></h3>
<div class="paragraph">
<p>The phonetic text (soundex) procedures allow you to compute the soundex encoding of a given string.
There is also a procedure to compare how similar two strings sound under the soundex algorithm.
All soundex procedures by default assume the used language is US English.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.text.phonetic('Hello, dear User!') YIELD value
RETURN value // will return 'H436'</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.text.phoneticDelta('Hello Mr Rabbit', 'Hello Mr Ribbit') // will return '4'  (very similar)</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_extract_domain"><a class="link" href="#_extract_domain">Extract Domain</a></h3>
<div class="paragraph">
<p>The User Function <code>apoc.data.domain</code> will take a url or email address and try to determine the domain name.
This can be useful to make easier correlations and equality tests between differently formatted email addresses, and between urls to the same domains but specifying different locations.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH 'foo@bar.com' AS email
RETURN apoc.data.domain(email) // will return 'bar.com'</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH 'http://www.example.com/all-the-things' AS url
RETURN apoc.data.domain(url) // will return 'www.example.com'</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_timetolive_ttl_expire_nodes"><a class="link" href="#_timetolive_ttl_expire_nodes">TimeToLive (TTL) - Expire Nodes</a></h4>
<div class="paragraph">
<p>Enable cleanup of expired nodes in <code>neo4j.conf</code> with <code>apoc.ttl.enabled=true</code></p>
</div>
<div class="paragraph">
<p>30s after startup an index is created:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE INDEX ON :TTL(ttl)</code></pre>
</div>
</div>
<div class="paragraph">
<p>At startup a statement is scheduled to run every 60s (or configure in <code>neo4j.conf</code> -  <code>apoc.ttl.schedule=120</code>)</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (t:TTL) where t.ttl &lt; timestamp() WITH t LIMIT 1000 DETACH DELETE t</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>ttl</code> property holds the <strong>time when the node is expired in milliseconds since epoch</strong>.</p>
</div>
<div class="paragraph">
<p>You can expire your nodes by setting the :TTL label and the ttl property:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (n:Foo) WHERE n.bar SET n:TTL, n.ttl = timestamp() + 10000;</code></pre>
</div>
</div>
<div class="paragraph">
<p>There is also a procedure that does the same:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.date.expire(node,time,'time-unit');
CALL apoc.date.expire(n,100,'s');</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_date_and_time_conversions"><a class="link" href="#_date_and_time_conversions">Date and Time Conversions</a></h3>
<div class="paragraph">
<p>(thanks @tkroman)</p>
</div>
<div class="sect3">
<h4 id="_conversion_between_formatted_dates_and_timestamps"><a class="link" href="#_conversion_between_formatted_dates_and_timestamps">Conversion between formatted dates and timestamps</a></h4>
<div class="ulist">
<ul>
<li>
<p><code>apoc.date.parse('2015/03/25 03-15-59',['s'],['yyyy/MM/dd HH/mm/ss'])</code> same as previous, but accepts custom datetime format</p>
</li>
<li>
<p><code>apoc.date.format(12345,['s'], ['yyyy/MM/dd HH/mm/ss'])</code> the same as previous, but accepts custom datetime format</p>
</li>
<li>
<p>possible unit values: <code>ms,s,m,h,d</code> and their long forms.</p>
</li>
<li>
<p>possible time zone values: Either an abbreviation such as <code>PST</code>, a full name such as <code>America/Los_Angeles</code>, or a custom ID such as <code>GMT-8:00</code>. Full names are recommended.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_conversion_of_timestamps_between_different_time_units"><a class="link" href="#_conversion_of_timestamps_between_different_time_units">Conversion of timestamps between different time units</a></h4>
<div class="ulist">
<ul>
<li>
<p><code>apoc.date.convert(12345, 'ms', 'd')</code> convert a timestamp in one time unit into one of a different time unit</p>
</li>
<li>
<p>possible unit values: <code>ms,s,m,h,d</code> and their long forms.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_adding_subtracting_time_unit_values_to_timestamps"><a class="link" href="#_adding_subtracting_time_unit_values_to_timestamps">Adding/subtracting time unit values to timestamps</a></h4>
<div class="ulist">
<ul>
<li>
<p><code>apoc.date.add(12345, 'ms', -365, 'd')</code> given a timestamp in one time unit, adds a value of the specified time unit</p>
</li>
<li>
<p>possible unit values: <code>ms,s,m,h,d</code> and their long forms.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_current_timestamp"><a class="link" href="#_current_timestamp">Current timestamp</a></h4>
<div class="paragraph">
<p><code>apoc.date.currentTimestamp()</code> provides the System.currentTimeMillis which is current throughout transaction execution compared to Cypher&#8217;s timestamp() function which does not update within a transaction</p>
</div>
</div>
<div class="sect3">
<h4 id="_reading_separate_datetime_fields"><a class="link" href="#_reading_separate_datetime_fields">Reading separate datetime fields:</a></h4>
<div class="paragraph">
<p>Splits date (optionally, using given custom format) into fields returning a map from field name to its value.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">RETURN apoc.date.fields('2015-03-25 03:15:59')</code></pre>
</div>
</div>
<div class="paragraph">
<p>Following fields are supported:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Result field</th>
<th class="tableblock halign-left valign-top">Represents</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'years'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">year</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'months'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">month of year</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'days'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">day of month</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'hours'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">hour of day</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'minutes'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">minute of hour</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'seconds'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">second of minute</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'zone'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://dohcs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html#timezone">time zone</a></p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_examples"><a class="link" href="#_examples">Examples</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">RETURN apoc.date.fields('2015-01-02 03:04:05 EET', 'yyyy-MM-dd HH:mm:ss zzz')</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>  {
    'weekdays': 5,
    'years': 2015,
    'seconds': 5,
    'zoneid': 'EET',
    'minutes': 4,
    'hours': 3,
    'months': 1,
    'days': 2
  }</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">RETURN apoc.date.fields('2015/01/02_EET', 'yyyy/MM/dd_z')</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>  {
    'weekdays': 5,
    'years': 2015,
    'zoneid': 'EET',
    'months': 1,
    'days': 2
  }</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_notes_on_formats"><a class="link" href="#_notes_on_formats">Notes on formats:</a></h4>
<div class="ulist">
<ul>
<li>
<p>the default format is <code>yyyy-MM-dd HH:mm:ss</code></p>
</li>
<li>
<p>if the format pattern doesn&#8217;t specify timezone, formatter considers dates to belong to the UTC timezone</p>
</li>
<li>
<p>if the timezone pattern is specified, the timezone is extracted from the date string, otherwise an error will be reported</p>
</li>
<li>
<p>the <code>to/fromSeconds</code> timestamp values are in POSIX (Unix time) system, i.e. timestamps represent the number of seconds elapsed since <a href="https://en.wikipedia.org/wiki/Unix_time">00:00:00 UTC, Thursday, 1 January 1970</a></p>
</li>
<li>
<p>the full list of supported formats is described in <a href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat JavaDoc</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_reading_single_datetime_field_from_utc_epoch"><a class="link" href="#_reading_single_datetime_field_from_utc_epoch">Reading single datetime field from UTC Epoch:</a></h4>
<div class="paragraph">
<p>Extracts the value of one field from a datetime epoch.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">RETURN apoc.date.field(12345)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Following fields are supported:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Result field</th>
<th class="tableblock halign-left valign-top">Represents</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'years'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">year</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'months'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">month of year</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'days'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">day of month</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'hours'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">hour of day</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'minutes'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">minute of hour</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'seconds'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">second of minute</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'millis'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">milliseconds of a second</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_examples_2"><a class="link" href="#_examples_2">Examples</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">RETURN apoc.date.field(12345, 'days')</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>    2</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_number_format_conversions"><a class="link" href="#_number_format_conversions">Number Format Conversions</a></h3>
<div class="sect3">
<h4 id="_conversion_between_formatted_decimals"><a class="link" href="#_conversion_between_formatted_decimals">Conversion between formatted decimals</a></h4>
<div class="ulist">
<ul>
<li>
<p><code>apoc.number.format(number)</code> format a long or double using the default system pattern and language to produce a string</p>
</li>
<li>
<p><code>apoc.number.format(number, pattern)</code> format a long or double using a pattern and the default system language to produce a string</p>
</li>
<li>
<p><code>apoc.number.format(number, lang)</code> format a long or double using the default system pattern pattern and a language to produce a string</p>
</li>
<li>
<p><code>apoc.number.format(number, pattern, lang)</code> format a long or double using a pattern and a language to produce a string</p>
</li>
<li>
<p><code>apoc.number.parseInt(text)</code> parse a text using the default system pattern and language to produce a long</p>
</li>
<li>
<p><code>apoc.number.parseInt(text, pattern)</code> parse a text using a pattern and the default system language to produce a long</p>
</li>
<li>
<p><code>apoc.number.parseInt(text, '', lang)</code> parse a text using the default system pattern and a language to produce a long</p>
</li>
<li>
<p><code>apoc.number.parseInt(text, pattern, lang)</code> parse a text using a pattern and a language to produce a long</p>
</li>
<li>
<p><code>apoc.number.parseFloat(text)</code> parse a text using the default system pattern and language to produce a double</p>
</li>
<li>
<p><code>apoc.number.parseFloat(text, pattern)</code> parse a text using a pattern and the default system language to produce a double</p>
</li>
<li>
<p><code>apoc.number.parseFloat(text,'',lang)</code> parse a text using the default system pattern and a language to produce a double</p>
</li>
<li>
<p><code>apoc.number.parseFloat(text, pattern, lang)</code> parse a text using a pattern and a language to produce a double</p>
</li>
<li>
<p>The full list of supported values for <code>pattern</code> and <code>lang</code> params is described in <a href="https://docs.oracle.com/javase/9/docs/api/java/text/DecimalFormat.html">DecimalFormat JavaDoc</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_examples_3"><a class="link" href="#_examples_3">Examples</a></h4>
<div class="literalblock">
<div class="content">
<pre>  return apoc.number.format(12345.67) as value

  ╒═════════╕
  │value    │
  ╞═════════╡
  │12,345.67│
  └─────────┘</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>  return apoc.number.format(12345, '#,##0.00;(#,##0.00)', 'it') as value

  ╒═════════╕
  │value    │
  ╞═════════╡
  │12.345,00│
  └─────────</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>  return apoc.number.format(12345.67, '#,##0.00;(#,##0.00)', 'it') as value

  ╒═════════╕
  │value    │
  ╞═════════╡
  │12.345,67│
  └─────────┘</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>  return apoc.number.parseInt('12.345', '#,##0.00;(#,##0.00)', 'it') as value

  ╒═════╕
  │value│
  ╞═════╡
  │12345│
  └─────┘</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>  return apoc.number.parseFloat('12.345,67', '#,##0.00;(#,##0.00)', 'it') as value

  ╒════════╕
  │value   │
  ╞════════╡
  │12345.67│
  └────────┘</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>  return apoc.number.format('aaa') as value

  null beacuse 'aaa' isn't a number</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>  RETURN apoc.number.parseInt('aaa')

  Return null because 'aaa' is unparsable.</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_exact"><a class="link" href="#_exact">Exact</a></h3>
<div class="sect3">
<h4 id="_handle_biginteger_and_bigdecimal"><a class="link" href="#_handle_biginteger_and_bigdecimal">Handle BigInteger And BigDecimal</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Statement</th>
<th class="tableblock halign-left valign-top">Description</th>
<th class="tableblock halign-left valign-top">Return type</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RETURN apoc.number.exact.add(stringA,stringB)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the sum&#8217;s result of two large numbers</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RETURN apoc.number.exact.sub(stringA,stringB)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the substraction&#8217;s of two large numbers</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RETURN apoc.number.exact.mul(stringA,stringB,[prec],[roundingModel]</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the multiplication&#8217;s result of two large numbers</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RETURN apoc.number.exact.div(stringA,stringB,[prec],[roundingModel])</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the division&#8217;s result of two large numbers</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RETURN apoc.number.exact.toInteger(string,[prec],[roundingMode])</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the Integer value of a large number</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Integer</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RETURN apoc.number.exact.toFloat(string,[prec],[roundingMode])</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the Float value of a large number</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Float</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">RETURN apoc.number.exact.toExact(number)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the exact value</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Integer</p></td>
</tr>
</tbody>
</table>
<div class="ulist">
<ul>
<li>
<p>Possible 'roundingModel' options are <code>UP</code>, <code>DOWN</code>, <code>CEILING</code>, <code>FLOOR</code>, <code>HALF_UP</code>, <code>HALF_DOWN</code>, <code>HALF_EVEN</code>, <code>UNNECESSARY</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>prec</code> parameter let us to set the precision of the operation result.
The default value is 0 (unlimited precision arithmetic) while for 'roundingModel' the default value is <code>HALF_UP</code>. For other information abouth <code>prec</code> and <code>roundingModel</code> see the documentation of <a href="https://docs.oracle.com/javase/7/docs/api/java/math/MathContext.html">MathContext</a></p>
</div>
<div class="paragraph">
<p>For example if we set as <code>prec</code> 2:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>  return apoc.number.exact.div('5555.5555','5', 2, 'HALF_DOWN') as value

  ╒═════════╕
  │value    │
  ╞═════════╡
  │  1100   │
  └─────────┘</pre>
</div>
</div>
<div class="paragraph">
<p>As a result we have only the first two digits precise.
If we set 8 we have all the result precise</p>
</div>
<div class="literalblock">
<div class="content">
<pre>  return apoc.number.exact.div('5555.5555','5', 8, 'HALF_DOWN') as value

  ╒═════════╕
  │value    │
  ╞═════════╡
  │1111.1111│
  └─────────┘</pre>
</div>
</div>
<div class="paragraph">
<p>All the functions accept as input the <strong>scientific notation</strong> as <code>1E6</code>, for example:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>  return apoc.number.exact.add('1E6','1E6') as value

  ╒═════════╕
  │value    │
  ╞═════════╡
  │ 2000000 │
  └─────────┘</pre>
</div>
</div>
<div class="paragraph">
<p>For other information see the documentation about <a href="https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#">BigDecimal</a> and <a href="https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#">BigInteger</a></p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_graph_algorithms"><a class="link" href="#_graph_algorithms">Graph Algorithms</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_algorithm_procedures"><a class="link" href="#_algorithm_procedures">Algorithm Procedures</a></h3>
<div class="sect3">
<h4 id="_community_detection_via_label_propagation"><a class="link" href="#_community_detection_via_label_propagation">Community Detection via Label Propagation</a></h4>
<div class="paragraph">
<p>APOC includes a simple procedure for label propagation.
It may be used to detect communities or solve other graph partitioning problems.
The following example shows how it may be used.</p>
</div>
<div class="paragraph">
<p>The example call with scan all nodes 25 times.
During a scan the procedure will look at all outgoing relationships of type :X for each node n.
For each of these relationships, it will compute a weight and use that as a vote for the other node&#8217;s 'partition' property value.
Finally, n.partition is set to the property value that acquired the most votes.</p>
</div>
<div class="paragraph">
<p>Weights are computed by multiplying the relationship weight with the weight of the other nodes.
Both weights are taken from the 'weight' property; if no such property is found, the weight is assumed to be 1.0.
Similarly, if no 'weight' property key was specified, all weights are assumed to be 1.0.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.algo.community(25,null,'partition','X','OUTGOING','weight',10000)</code></pre>
</div>
</div>
<div class="paragraph">
<p>The second argument is a list of label names and may be used to restrict which nodes are scanned.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_expand_paths"><a class="link" href="#_expand_paths">Expand paths</a></h3>
<div class="paragraph">
<p>Expand from start node following the given relationships from min to max-level adhering to the label filters. Several variations exist:</p>
</div>
<div class="paragraph">
<p><code>apoc.path.expand()</code> expands paths using Cypher&#8217;s default expansion modes (bfs and 'RELATIONSHIP_PATH' uniqueness)</p>
</div>
<div class="paragraph">
<p><code>apoc.path.expandConfig()</code> allows more flexible configuration of parameters and expansion modes</p>
</div>
<div class="paragraph">
<p><code>apoc.path.subgraphNodes()</code> expands to nodes of a subgraph</p>
</div>
<div class="paragraph">
<p><code>apoc.path.subgraphAll()</code> expands to nodes of a subgraph and also returns all relationships in the subgraph</p>
</div>
<div class="paragraph">
<p><code>apoc.path.spanningTree()</code> expands to paths collectively forming a spanning tree</p>
</div>
<div class="sect3">
<h4 id="_expand"><a class="link" href="#_expand">Expand</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.path.expand(startNode &lt;id&gt;|Node, relationshipFilter, labelFilter, minLevel, maxLevel )

CALL apoc.path.expand(startNode &lt;id&gt;|Node|list, 'TYPE|TYPE_OUT&gt;|&lt;TYPE_IN', '+YesLabel|-NoLabel|/TerminationLabel|&gt;EndNodeLabel', minLevel, maxLevel ) yield path</code></pre>
</div>
</div>
<div class="sect5">
<h6 id="_relationship_filter"><a class="link" href="#_relationship_filter">Relationship Filter</a></h6>
<div class="paragraph">
<p>Syntax: <code>[&lt;]RELATIONSHIP_TYPE1[&gt;]|[&lt;]RELATIONSHIP_TYPE2[&gt;]|&#8230;&#8203;</code></p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">input</th>
<th class="tableblock halign-left valign-top">type</th>
<th class="tableblock halign-left valign-top">direction</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>LIKES&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>LIKES</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>OUTGOING</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>&lt;FOLLOWS</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FOLLOWS</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>INCOMING</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>KNOWS</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>KNOWS</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>BOTH</p>
</div></div></td>
</tr>
</tbody>
</table>
</div>
<div class="sect5">
<h6 id="_label_filter"><a class="link" href="#_label_filter">Label Filter</a></h6>
<div class="paragraph">
<p>Syntax: <code>[+-/&gt;]LABEL1|LABEL2|*|&#8230;&#8203;</code></p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">input</th>
<th class="tableblock halign-left valign-top">result</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>-Foe</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>blacklist filter - No node in the path will have a label in the blacklist.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>+Friend</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>whitelist filter - All nodes in the path must have a label in the whitelist (exempting termination and end nodes, if using those filters).
If no whitelist operator is present, all labels are considered whitelisted.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/Friend</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>termination filter - Only return paths up to a node of the given labels, and stop further expansion beyond it.
Termination nodes do not have to respect the whitelist. Termination filtering takes precedence over end node filtering.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>&gt;Friend</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>end node filter - Only return paths up to a node of the given labels, but continue expansion to match on end nodes beyond it.
End nodes do not have to respect the whitelist to be returned, but expansion beyond them is only allowed if the node has a label in the whitelist.</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<div class="title">Syntax Changes</div>
<p>As of APOC 3.1.3.x multiple label filter operations are allowed.
In prior versions, only one type of operation is allowed in the label filter (<code>+</code> or <code>-</code> or <code>/</code> or <code>&gt;</code>, never more than one).</p>
</div>
<div class="paragraph">
<p>With APOC 3.2.x.x, label filters will no longer apply to starting nodes of the expansion by default, but this can be toggled with the <code>filterStartNode</code> config parameter.</p>
</div>
<div class="paragraph">
<p>With the APOC releases in January 2018, some behavior has changed in the label filters:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">filter</th>
<th class="tableblock halign-left valign-top">changed behavior</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>No filter</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Now indicates the label is whitelisted, same as if it were prefixed with <code>+</code>.
Previously, a label without a filter symbol reused the previously used symbol.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code><code>&gt;</code> (end node filter)</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>The label is additionally whitelisted, so expansion will always continue beyond an end node (unless prevented by the blacklist).
Previously, expansion would only continue if allowed by the whitelist and not disallowed by the blacklist.
This also applies at a depth below <code>minLevel</code>, allowing expansion to continue.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code><code>/</code> (termination filter)</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>When at depth below <code>minLevel</code>, expansion is allowed to continue and no pruning will take place (unless prevented by the blacklist).
Previously, expansion would only continue if allowed by the whitelist and not disallowed by the blacklist.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>All filters</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><code>*</code> is allowed as a standin for all labels.
Additionally, compound labels are supported (like <code>Person:Manager</code>), and only apply to nodes with all of those labels present (order agnositic).</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="listingblock">
<div class="title">Examples</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.path.expand(1,"ACTED_IN&gt;|PRODUCED&lt;|FOLLOWS&lt;","+Movie|Person",0,3)
call apoc.path.expand(1,"ACTED_IN&gt;|PRODUCED&lt;|FOLLOWS&lt;","-BigBrother",0,3)
call apoc.path.expand(1,"ACTED_IN&gt;|PRODUCED&lt;|FOLLOWS&lt;","",0,3)

// combined with cypher:

match (tom:Person {name :"Tom Hanks"})
call apoc.path.expand(tom,"ACTED_IN&gt;|PRODUCED&lt;|FOLLOWS&lt;","+Movie|Person",0,3) yield path as pp
return pp;

// or

match (p:Person) with p limit 3
call apoc.path.expand(p,"ACTED_IN&gt;|PRODUCED&lt;|FOLLOWS&lt;","+Movie|Person",1,2) yield path as pp
return p, pp</code></pre>
</div>
</div>
<div class="paragraph">
<div class="title">Termination and end node label filter example</div>
<p>We will first set a <code>:Western</code> label on some nodes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">match (p:Person)
where p.name in ['Clint Eastwood', 'Gene Hackman']
set p:Western</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now expand from 'Keanu Reeves' to all <code>:Western</code> nodes with a termination filter:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">match (k:Person {name:'Keanu Reeves'})
call apoc.path.expandConfig(k, {relationshipFilter:'ACTED_IN|PRODUCED|DIRECTED', labelFilter:'/Western', uniqueness: 'NODE_GLOBAL'}) yield path
return path</code></pre>
</div>
</div>
<div class="paragraph">
<p>The one returned path only matches up to 'Gene Hackman'.
While there is a path from 'Keanu Reeves' to 'Clint Eastwood' through 'Gene Hackman', no further expansion is permitted through a node in the termination filter.</p>
</div>
<div class="paragraph">
<p>If you didn&#8217;t want to stop expansion on reaching 'Gene Hackman', and wanted 'Clint Eastwood' returned as well, use the end node filter  instead (<code>&gt;</code>).</p>
</div>
<div class="paragraph">
<div class="title">Label filter operator precedence and behavior</div>
<p>As of APOC 3.1.3.x, multiple label filter operators are allowed at the same time.</p>
</div>
<div class="paragraph">
<p>When processing the labelFilter string, once a filter operator is introduced, it remains the active filter until another filter supplants it.
(Not applicable after February 2018 release, as no filter will now mean the label is whitelisted).</p>
</div>
<div class="paragraph">
<p>In the following example, <code>:Person</code> and <code>:Movie</code> labels are whitelisted, <code>:SciFi</code> is blacklisted, with <code>:Western</code> acting as an end node label, and <code>:Romance</code> acting as a termination label.</p>
</div>
<div class="paragraph">
<p><code>&#8230;&#8203; labelFilter:'+Person|Movie|-SciFi|&gt;Western|/Romance' &#8230;&#8203;</code></p>
</div>
<div class="paragraph">
<p>The precedence of operator evaluation isn&#8217;t dependent upon their location in the labelFilter but is fixed:</p>
</div>
<div class="paragraph">
<p>Blacklist filter <code>-</code>, termination filter <code>/</code>, end node filter <code>&gt;</code>, whitelist filter <code>+</code>.</p>
</div>
<div class="paragraph">
<p>The consequences are as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>No blacklisted label <code>-</code> will ever be present in the nodes of paths returned, no matter if the same label (or another label of a node with a blacklisted label) is included in another filter list.</p>
</li>
<li>
<p>If the termination filter <code>/</code> or end node filter <code>&gt;</code> is used, then only paths up to nodes with those labels will be returned as results. These end nodes are exempt from the whitelist filter.</p>
</li>
<li>
<p>If a node is a termination node <code>/</code>, no further expansion beyond the node will occur.</p>
</li>
<li>
<p>If a node is an end node <code>&gt;</code>, expansion beyond that node will only occur if the end node has a label in the whitelist. This is to prevent returning paths to nodes where a node on that path violates the whitelist.
(this no longer applies in releases after February 2018)</p>
</li>
<li>
<p>The whitelist only applies to nodes up to but not including end nodes from the termination or end node filters. If no end node or termination node operators are present, then the whitelist applies to all nodes of the path.</p>
</li>
<li>
<p>If no whitelist operators are present in the labelFilter, this is treated as if all labels are whitelisted.</p>
</li>
<li>
<p>If <code>filterStartNode</code> is false (which will be default in APOC 3.2.x.x), then the start node is exempt from the label filter.</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="_sequences"><a class="link" href="#_sequences">Sequences</a></h5>
<div class="paragraph">
<p>Introduced in the February 2018 APOC releases, path expander procedures can expand on repeating sequences of labels, relationship types, or both.</p>
</div>
<div class="paragraph">
<p>If only using label sequences, just use the <code>labelFilter</code>, but use commas to separate the filtering for each step in the repeating sequence.</p>
</div>
<div class="paragraph">
<p>If only using relationship sequences, just use the <code>relationshipFilter</code>, but use commas to separate the filtering for each step of the repeating sequence.</p>
</div>
<div class="paragraph">
<p>If using sequences of both relationships and labels, use the <code>sequence</code> parameter.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Usage</th>
<th class="tableblock halign-left valign-top">config param</th>
<th class="tableblock halign-left valign-top">description</th>
<th class="tableblock halign-left valign-top">syntax</th>
<th class="tableblock halign-left valign-top">explanation</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>label sequences only</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>labelFilter</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Same syntax and filters, but uses commas (<code>,</code>) to separate the filters for each step in the sequence.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>labelFilter:'Post|-Blocked,Reply,&gt;Admin'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Start node must be a :Post node that isn&#8217;t :Blocked, next node must be a :Reply, and the next must be an :Admin, then repeat if able. Only paths ending with the <code>:Admin</code> node in that position of the sequence will be returned.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>relationship sequences only</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>relationshipFilter</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Same syntax, but uses commas (<code>,</code>) to separate the filters for each relationship traversal in the sequence.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>relationshipFilter:'NEXT&gt;,&lt;FROM,POSTED&gt;|REPLIED&gt;'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Expansion will first expand <code>NEXT&gt;</code> from the start node, then <code>&lt;FROM</code>, then either <code>POSTED&gt;</code> or <code>REPLIED&gt;</code>, then repeat if able.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>sequences of both labels and relationships</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sequence</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>A string of comma-separated alternating label and relationship filters, for each step in a repeating sequence. The sequence should begin with a label filter, and end with a relationship filter. If present, <code>labelFilter</code>, and <code>relationshipFilter</code> are ignored, as this takes priority.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sequence:'Post|-Blocked, NEXT&gt;, Reply, &lt;FROM, &gt;Admin, POSTED&gt;|REPLIED&gt;'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Combines the behaviors above.</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="sect5">
<h6 id="_starting_the_sequence_at_one_off_from_the_start_node"><a class="link" href="#_starting_the_sequence_at_one_off_from_the_start_node">Starting the sequence at one-off from the start node</a></h6>
<div class="paragraph">
<p>There are some uses cases where the sequence does not begin at the start node, but at one node distant.</p>
</div>
<div class="paragraph">
<p>A new config parameter, <code>beginSequenceAtStart</code>, can toggle this behavior.</p>
</div>
<div class="paragraph">
<p>Default value is <code>true</code>.</p>
</div>
<div class="paragraph">
<p>If set to <code>false</code>, this changes the expected values for <code>labelFilter</code>, <code>relationshipFilter</code>, and <code>sequence</code> as noted below:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">sequence</th>
<th class="tableblock halign-left valign-top">altered behavior</th>
<th class="tableblock halign-left valign-top">example</th>
<th class="tableblock halign-left valign-top">explanation</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>labelFilter</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>The start node is not considered part of the sequence. The sequence begins one node off from the start node.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>beginSequenceAtStart:false, labelFilter:'Post|-Blocked,Reply,&gt;Admin'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>The next node(s) out from the start node begins the sequence (and must be a :Post node that isn&#8217;t :Blocked), and only paths ending with <code>Admin</code> nodes returned.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>relationshipFilter</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>The first relationship filter in the sequence string will not be considered part of the repeating sequence, and will only be used for the first relationship from the start node to the node that will be the actual start of the sequence.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>beginSequenceAtStart:false, relationshipFilter:'FIRST&gt;,NEXT&gt;,&lt;FROM,POSTED&gt;|REPLIED&gt;'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><code>FIRST&gt;</code> will be traversed just from the start node to the node that will be the start of the repeating <code>NEXT&gt;,&lt;FROM,POSTED&gt;|REPLIED&gt;</code> sequence.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sequence</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Combines the above two behaviors.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>beginSequenceAtStart:false, sequence:'FIRST&gt;, Post|-Blocked, NEXT&gt;, Reply, &lt;FROM, &gt;Admin, POSTED&gt;|REPLIED&gt;'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Combines the behaviors above.</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<div class="title">Sequence tips</div>
<p>Label filtering in sequences work together with the <code>endNodes</code>+<code>terminatorNodes</code>, though inclusion of a node must be unanimous.</p>
</div>
<div class="paragraph">
<p>Remember that <code>filterStartNode</code> defaults to <code>false</code> for APOC 3.2.x.x and newer. If you want the start node filtered according to the first step in the sequence, you may need to set this explicitly to <code>true</code>.</p>
</div>
<div class="paragraph">
<p>If you need to limit the number of times a sequence repeats, this can be done with the <code>maxLevel</code> config param (multiply the number of iterations with the size of the nodes in the sequence).</p>
</div>
<div class="paragraph">
<p>As paths are important when expanding sequences, we recommend avoiding <code>apoc.path.subgraphNodes()</code>, <code>apoc.path.subgraphAll()</code>, and <code>apoc.path.spanningTree()</code> when using sequences,
as the configurations that make these efficient at matching to distinct nodes may interfere with sequence pathfinding.</p>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_expand_with_config"><a class="link" href="#_expand_with_config">Expand with Config</a></h4>
<div class="listingblock">
<div class="content">
<pre>apoc.path.expandConfig(startNode &lt;id&gt;Node/list, {config}) yield path expands from start nodes using the given configuration and yields the resulting paths</pre>
</div>
</div>
<div class="paragraph">
<p>Takes an additional map parameter, <code>config</code>, to provide configuration options:</p>
</div>
<div class="listingblock">
<div class="title">Config</div>
<div class="content">
<pre>{minLevel: -1|number,
 maxLevel: -1|number,
 relationshipFilter: '[&lt;]RELATIONSHIP_TYPE1[&gt;]|[&lt;]RELATIONSHIP_TYPE2[&gt;], [&lt;]RELATIONSHIP_TYPE3[&gt;]|[&lt;]RELATIONSHIP_TYPE4[&gt;]',
 labelFilter: '[+-/&gt;]LABEL1|LABEL2|*,[+-/&gt;]LABEL1|LABEL2|*,...',
 uniqueness: RELATIONSHIP_PATH|NONE|NODE_GLOBAL|NODE_LEVEL|NODE_PATH|NODE_RECENT|
             RELATIONSHIP_GLOBAL|RELATIONSHIP_LEVEL|RELATIONSHIP_RECENT,
 bfs: true|false,
 filterStartNode: true|false,
 limit: -1|number,
 optional: true|false,
 endNodes: [nodes],
 terminatorNodes: [nodes],
 beginSequenceAtStart: true|false}</pre>
</div>
</div>
<div class="paragraph">
<div class="title">Start Node and label filters</div>
<p>The config parameter <code>filterStartNode</code> defines whether or not the labelFilter (and <code>sequence</code>) applies to the start node of the expansion.</p>
</div>
<div class="paragraph">
<p>Use <code>filterStartNode: false</code> when you want your label filter to only apply to all other nodes in the path, ignoring the start node.</p>
</div>
<div class="paragraph">
<p><code>filterStartNode</code> defaults for all path expander procedures:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">version</th>
<th class="tableblock halign-left valign-top">default</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>&gt;= APOC 3.2.x.x</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>filterStartNode = false</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>&lt; APOC 3.2.x.x</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>filterStartNode = true</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<div class="title">Limit</div>
<p>You can use the <code>limit</code> config parameter to limit the number of paths returned.</p>
</div>
<div class="paragraph">
<p>When using <code>bfs:true</code> (which is the default for all expand procedures), this has the effect of returning paths to the <code>n</code> nearest nodes with labels in the termination or end node filter, where <code>n</code> is the limit given.</p>
</div>
<div class="paragraph">
<p>The default limit value, <code>-1</code>, means no limit.</p>
</div>
<div class="paragraph">
<p>If you want to make sure multiple paths should never match to the same node, use <code>expandConfig()</code> with 'NODE_GLOBAL' uniqueness, or any expand procedure which already uses this uniqueness
(<code>subgraphNodes()</code>, <code>subgraphAll()</code>, and <code>spanningTree()</code>).</p>
</div>
<div class="paragraph">
<div class="title">Optional</div>
<p>When <code>optional</code> is set to true, the path expansion is optional, much like an OPTIONAL MATCH, so a <code>null</code> value is yielded whenever the expansion would normally eliminate rows due to no results.</p>
</div>
<div class="paragraph">
<p>By default <code>optional</code> is false for all expansion procedures taking a config parameter.</p>
</div>
<div class="paragraph">
<div class="title">Uniqueness</div>
<p>Uniqueness of nodes and relationships guides the expansion and the results returned.
Uniqueness is only configurable using <code>expandConfig()</code>.</p>
</div>
<div class="paragraph">
<p><code>subgraphNodes()</code>, <code>subgraphAll()</code>, and <code>spanningTree()</code> all use 'NODE_GLOBAL' uniqueness.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">value</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>RELATIONSHIP_PATH</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>For each returned node there&#8217;s a (relationship wise) unique path from the start node to it. This is Cypher&#8217;s default expansion mode.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NODE_GLOBAL</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>A node cannot be traversed more than once. This is what the legacy traversal framework does.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NODE_LEVEL</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Entities on the same level are guaranteed to be unique.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NODE_PATH</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>For each returned node there&#8217;s a unique path from the start node to it.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NODE_RECENT</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>This is like NODE_GLOBAL, but only guarantees uniqueness among the most recent visited nodes, with a configurable count. Traversing a huge graph is quite memory intensive in that it keeps track of all the nodes it has visited.
For huge graphs a traverser can hog all the memory in the JVM, causing OutOfMemoryError. Together with this Uniqueness you can supply a count, which is the number of most recent visited nodes. This can cause a node to be visited more than once, but scales infinitely.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>RELATIONSHIP_GLOBAL</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>A relationship cannot be traversed more than once, whereas nodes can.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>RELATIONSHIP_LEVEL</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Entities on the same level are guaranteed to be unique.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>RELATIONSHIP_RECENT</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Same as for NODE_RECENT, but for relationships.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NONE</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>No restriction (the user will have to manage it)</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<div class="title">endNodes and terminatorNodes</div>
<p>As of the February 2018 APOC releases, if the end nodes of the expansion are known ahead of time (such as when testing reachability), then these nodes can be passed in as <code>endNodes</code> or <code>terminatorNodes</code>.</p>
</div>
<div class="paragraph">
<p>This restricts the returned paths (or nodes) to only these nodes (or nodes with the given ids, if an integer list is passed).</p>
</div>
<div class="paragraph">
<p>For <code>endNodes</code>, expansion continues past end nodes.</p>
</div>
<div class="paragraph">
<p>For <code>terminatorNodes</code>, expansion down a path stops when a terminator node is reached.</p>
</div>
<div class="paragraph">
<div class="title">General Examples</div>
<p>You can turn this cypher query:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (user:User) WHERE user.id = 460
MATCH (user)-[:RATED]-&gt;(movie)&lt;-[:RATED]-(collab)-[:RATED]-&gt;(reco)
RETURN count(*);</code></pre>
</div>
</div>
<div class="paragraph">
<p>into this procedure call, with changed semantics for uniqueness and bfs (which is Cypher&#8217;s expand mode)</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (user:User) WHERE user.id = 460
CALL apoc.path.expandConfig(user,{relationshipFilter:"RATED",minLevel:3,maxLevel:3,bfs:false,uniqueness:"NONE"}) YIELD path
RETURN count(*);</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_expand_to_nodes_in_a_subgraph"><a class="link" href="#_expand_to_nodes_in_a_subgraph">Expand to nodes in a subgraph</a></h4>
<div class="listingblock">
<div class="content">
<pre>apoc.path.subgraphNodes(startNode &lt;id&gt;Node/list, {maxLevel, relationshipFilter, labelFilter, bfs:true, filterStartNode:true, limit:-1, optional:false}) yield node</pre>
</div>
</div>
<div class="paragraph">
<p>Expand to subgraph nodes reachable from the start node following relationships to max-level adhering to the label filters.</p>
</div>
<div class="paragraph">
<p>Accepts the same <code>config</code> values as in <code>expandConfig()</code>, though <code>uniqueness</code> and <code>minLevel</code> are not configurable.</p>
</div>
<div class="paragraph">
<div class="title">Examples</div>
<p>Expand to all nodes of a connected subgraph:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (user:User) WHERE user.id = 460
CALL apoc.path.subgraphNodes(user, {}) YIELD node
RETURN node;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Expand to all nodes reachable by :FRIEND relationships:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (user:User) WHERE user.id = 460
CALL apoc.path.subgraphNodes(user, {relationshipFilter:'FRIEND'}) YIELD node
RETURN node;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_expand_to_a_subgraph_and_return_all_nodes_and_relationships_within_the_subgraph"><a class="link" href="#_expand_to_a_subgraph_and_return_all_nodes_and_relationships_within_the_subgraph">Expand to a subgraph and return all nodes and relationships within the subgraph</a></h4>
<div class="listingblock">
<div class="content">
<pre>apoc.path.subgraphAll(startNode &lt;id&gt;Node/list, {maxLevel, relationshipFilter, labelFilter, bfs:true, filterStartNode:true, limit:-1}) yield nodes, relationships</pre>
</div>
</div>
<div class="paragraph">
<p>Expand to subgraph nodes reachable from the start node following relationships to max-level adhering to the label filters.
Returns the collection of nodes in the subgraph, and the collection of relationships between all subgraph nodes.</p>
</div>
<div class="paragraph">
<p>Accepts the same <code>config</code> values as in <code>expandConfig()</code>, though <code>uniqueness</code> and <code>minLevel</code> are not configurable.</p>
</div>
<div class="paragraph">
<p>The <code>optional</code> config value isn&#8217;t needed, as empty lists are yielded if there are no results, so rows are never eliminated.</p>
</div>
<div class="paragraph">
<div class="title">Example</div>
<p>Expand to local subgraph (and all its relationships) within 4 traversals:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (user:User) WHERE user.id = 460
CALL apoc.path.subgraphAll(user, {maxLevel:4}) YIELD nodes, relationships
RETURN nodes, relationships;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_expand_a_spanning_tree"><a class="link" href="#_expand_a_spanning_tree">Expand a spanning tree</a></h4>
<div class="listingblock">
<div class="content">
<pre>apoc.path.spanningTree(startNode &lt;id&gt;Node/list, {maxLevel, relationshipFilter, labelFilter, bfs:true, filterStartNode:true, limit:-1, optional:false}) yield path</pre>
</div>
</div>
<div class="paragraph">
<p>Expand a spanning tree reachable from start node following relationships to max-level adhering to the label filters.
The paths returned collectively form a spanning tree.</p>
</div>
<div class="paragraph">
<p>Accepts the same <code>config</code> values as in <code>expandConfig()</code>, though <code>uniqueness</code> and <code>minLevel</code> are not configurable.</p>
</div>
<div class="paragraph">
<div class="title">Example</div>
<p>Expand a spanning tree of all contiguous :User nodes:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (user:User) WHERE user.id = 460
CALL apoc.path.spanningTree(user, {labelFilter:'+User'}) YIELD path
RETURN path;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_centrality_algorithms"><a class="link" href="#_centrality_algorithms">Centrality Algorithms</a></h3>
<div class="sect3">
<h4 id="_setup"><a class="link" href="#_setup">Setup</a></h4>
<div class="paragraph">
<p>Let&#8217;s create some test data to run the Centrality algorithms on.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">// create 100 nodes
FOREACH (id IN range(0,1000) | CREATE (:Node {id:id}))

// over the cross product (1M) create 100.000 relationships
MATCH (n1:Node),(n2:Node) WITH n1,n2 LIMIT 1000000 WHERE rand() &lt; 0.1

CREATE (n1)-[:TYPE]-&gt;(n2)</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_closeness_centrality_procedure"><a class="link" href="#_closeness_centrality_procedure">Closeness Centrality Procedure</a></h4>
<div class="paragraph">
<p>Centrality is an indicator of a node&#8217;s influence in a graph. In graphs there is a natural distance metric between pairs of nodes, defined by the length of their shortest paths.
For both algorithms below we can measure based upon the direction of the relationship, whereby the 3rd argument represents the direction
and can be of value BOTH, INCOMING, OUTGOING.</p>
</div>
<div class="paragraph">
<p>Closeness Centrality defines the farness of a node as the sum of its distances from all other nodes, and its closeness as the reciprocal of farness.</p>
</div>
<div class="paragraph">
<p>The more central a node is the lower its total distance from all other nodes.</p>
</div>
<div class="paragraph">
<p>Complexity: This procedure uses a BFS shortest path algorithm. With BFS the complexes becomes <code>O(n * m)</code>
Caution: Due to the complexity of this algorithm it is recommended to run it on only the nodes you are interested in.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (node:Node)
WHERE node.id %2 = 0
WITH collect(node) AS nodes
CALL apoc.algo.closeness(['TYPE'],nodes,'INCOMING') YIELD node, score
RETURN node, score
ORDER BY score DESC</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_betweenness_centrality_procedure"><a class="link" href="#_betweenness_centrality_procedure">Betweenness Centrality Procedure</a></h4>
<div class="paragraph">
<p>The procedure will compute betweenness centrality as defined by Linton C. Freeman (1977) using the algorithm by Ulrik Brandes (2001).
Centrality is an indicator of a node&#8217;s influence in a graph.</p>
</div>
<div class="paragraph">
<p>Betweenness Centrality is equal to the number of shortest paths from all nodes to all others that pass through that node.</p>
</div>
<div class="paragraph">
<p>High centrality suggests a large influence on the transfer of items through the graph.</p>
</div>
<div class="paragraph">
<p>Centrality is applicable to numerous domains, including: social networks, biology, transport and scientific cooperation.</p>
</div>
<div class="paragraph">
<p>Complexity: This procedure uses a BFS shortest path algorithm. With BFS the complexes becomes O(n * m)
Caution: Due to the complexity of this algorithm it is recommended to run it on only the nodes you are interested in.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (node:Node)
WHERE node.id %2 = 0
WITH collect(node) AS nodes
CALL apoc.algo.betweenness(['TYPE'],nodes,'BOTH') YIELD node, score
RETURN node, score
ORDER BY score DESC</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_pagerank_algorithm"><a class="link" href="#_pagerank_algorithm">PageRank Algorithm</a></h3>
<div class="sect3">
<h4 id="_setup_2"><a class="link" href="#_setup_2">Setup</a></h4>
<div class="paragraph">
<p>Let&#8217;s create some test data to run the PageRank algorithm on.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">// create 100 nodes
FOREACH (id IN range(0,1000) | CREATE (:Node {id:id}))

// over the cross product (1M) create 100.000 relationships
MATCH (n1:Node),(n2:Node) WITH n1,n2 LIMIT 1000000 WHERE rand() &lt; 0.1

CREATE (n1)-[:TYPE_1]-&gt;(n2)</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_pagerank_procedure"><a class="link" href="#_pagerank_procedure">PageRank Procedure</a></h4>
<div class="paragraph">
<p>PageRank is an algorithm used by Google Search to rank websites in their search engine results.</p>
</div>
<div class="paragraph">
<p>It is a way of measuring the importance of nodes in a graph.</p>
</div>
<div class="paragraph">
<p>PageRank counts the number and quality of relationships to a node to approximate the importance of that node.</p>
</div>
<div class="paragraph">
<p>PageRank assumes that more important nodes likely have more relationships.</p>
</div>
<div class="paragraph">
<p>Caution: <code>nodes</code> specifies the nodes for which a PageRank score will be projected, but the procedure will <em>always</em> compute the PageRank algorithm on the <em>entire</em> graph. At present, there is no way to filter/reduce the number of elements that PageRank computes over.</p>
</div>
<div class="paragraph">
<p>A future version of this procedure will provide the option of computing PageRank on a subset of the graph.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (node:Node)
WHERE node.id %2 = 0
WITH collect(node) AS nodes
// compute over relationships of all types
CALL apoc.algo.pageRank(nodes) YIELD node, score
RETURN node, score
ORDER BY score DESC</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (node:Node)
WHERE node.id %2 = 0
WITH collect(node) AS nodes
// only compute over relationships of types TYPE_1 or TYPE_2
CALL apoc.algo.pageRankWithConfig(nodes,{types:'TYPE_1|TYPE_2'}) YIELD node, score
RETURN node, score
ORDER BY score DESC</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (node:Node)
WHERE node.id %2 = 0
WITH collect(node) AS nodes
// peroform 10 page rank iterations, computing only over relationships of type TYPE_1
CALL apoc.algo.pageRankWithConfig(nodes,{iterations:10,types:'TYPE_1'}) YIELD node, score
RETURN node, score
ORDER BY score DESC</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_spatial"><a class="link" href="#_spatial">Spatial</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_spatial_functions"><a class="link" href="#_spatial_functions">Spatial Functions</a></h3>
<div class="paragraph">
<p>The spatial procedures are intended to enable geographic capabilities on your data.</p>
</div>
<div class="sect3">
<h4 id="_geocode"><a class="link" href="#_geocode">geocode</a></h4>
<div class="paragraph">
<p>The first procedure <em>geocode</em> which will convert a textual address
into a location containing <em>latitude</em>, <em>longitude</em> and <em>description</em>. Despite being
only a single function, together with the built-in functions <em>point</em> and <em>distance</em>
we can achieve quite powerful results.</p>
</div>
<div class="paragraph">
<p>First, how can we use the procedure:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.spatial.geocodeOnce('21 rue Paul Bellamy 44000 NANTES FRANCE') YIELD location
RETURN location.latitude, location.longitude // will return 47.2221667, -1.5566624</code></pre>
</div>
</div>
<div class="paragraph">
<p>There are two forms of the procedure:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>geocodeOnce(address) returns zero or one result</p>
</li>
<li>
<p>geocode(address,maxResults) returns zero, one or more up to maxResults</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>This is because the backing geocoding service (OSM, Google, OpenCage or other) might return multiple
results for the same query. GeocodeOnce() is designed to return the first, or highest
ranking result.</p>
</div>
</div>
<div class="sect3">
<h4 id="_configuring_geocode"><a class="link" href="#_configuring_geocode">Configuring Geocode</a></h4>
<div class="paragraph">
<p>There are a few options that can be set in the neo4j.conf file to control the service:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>apoc.spatial.geocode.provider=osm (osm, google, opencage, etc.)</p>
</li>
<li>
<p>apoc.spatial.geocode.osm.throttle=5000 (ms to delay between queries to not overload OSM servers)</p>
</li>
<li>
<p>apoc.spatial.geocode.google.throttle=1 (ms to delay between queries to not overload Google servers)</p>
</li>
<li>
<p>apoc.spatial.geocode.google.key=xxxx (API key for google geocode access)</p>
</li>
<li>
<p>apoc.spatial.geocode.google.client=xxxx (client code for google geocode access)</p>
</li>
<li>
<p>apoc.spatial.geocode.google.signature=xxxx (client signature for google geocode access)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For google, you should use either a key or a combination of client and signature. Read more
about this on the google page for geocode access at
<a href="https://developers.google.com/maps/documentation/geocoding/get-api-key#key" class="bare">https://developers.google.com/maps/documentation/geocoding/get-api-key#key</a></p>
</div>
</div>
<div class="sect3">
<h4 id="_configuring_custom_geocode_provider"><a class="link" href="#_configuring_custom_geocode_provider">Configuring Custom Geocode Provider</a></h4>
<div class="paragraph">
<p>For any provider that is not 'osm' or 'google' you get a configurable supplier that requires two
additional settings, 'url' and 'key'. The 'url' must contain the two words 'PLACE' and 'KEY'.
The 'KEY' will be replaced with the key you get from the provider when you register for the service.
The 'PLACE' will be replaced with the address to geocode when the procedure is called.</p>
</div>
<div class="paragraph">
<p>For example, to get the service working with OpenCage, perform the following steps:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Register your own application key at <a href="https://geocoder.opencagedata.com/" class="bare">https://geocoder.opencagedata.com/</a></p>
</li>
<li>
<p>Once you have a key, add the following three lines to neo4j.conf</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre>apoc.spatial.geocode.provider=opencage
apoc.spatial.geocode.opencage.key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
apoc.spatial.geocode.opencage.url=http://api.opencagedata.com/geocode/v1/json?q=PLACE&amp;key=KEY</pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>make sure that the 'XXXXXXX' part above is replaced with your actual key</p>
</li>
<li>
<p>Restart the Neo4j server and then test the geocode procedures to see that they work</p>
</li>
<li>
<p>If you are unsure if the provider is correctly configured try verify with:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.spatial.showConfig()</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_using_geocode_within_a_bigger_cypher_query"><a class="link" href="#_using_geocode_within_a_bigger_cypher_query">Using Geocode within a bigger Cypher query</a></h4>
<div class="paragraph">
<p>A more complex, or useful, example which geocodes addresses found in properties of nodes:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (a:Place)
WHERE exists(a.address)
CALL apoc.spatial.geocodeOnce(a.address) YIELD location
RETURN location.latitude AS latitude, location.longitude AS longitude, location.description AS description</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_calculating_distance_between_locations"><a class="link" href="#_calculating_distance_between_locations">Calculating distance between locations</a></h4>
<div class="paragraph">
<p>If we wish to calculate the distance between addresses, we need to use the point() function to convert
latitude and longitude to Cyper Point types, and then use the distance() function to calculate the distance:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH point({latitude: 48.8582532, longitude: 2.294287}) AS eiffel
MATCH (a:Place)
WHERE exists(a.address)
CALL apoc.spatial.geocodeOnce(a.address) YIELD location
WITH location, distance(point(location), eiffel) AS distance
WHERE distance &lt; 5000
RETURN location.description AS description, distance
ORDER BY distance
LIMIT 100</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_sortpathsbydistance"><a class="link" href="#_sortpathsbydistance">sortPathsByDistance</a></h5>
<div class="paragraph">
<p>The second procedure enables you to sort a given collection of paths by the sum of their distance based on lat/long properties
on the nodes.</p>
</div>
<div class="paragraph">
<p>Sample data :</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (bruges:City {name:"bruges", latitude: 51.2605829, longitude: 3.0817189})
CREATE (brussels:City {name:"brussels", latitude: 50.854954, longitude: 4.3051786})
CREATE (paris:City {name:"paris", latitude: 48.8588376, longitude: 2.2773455})
CREATE (dresden:City {name:"dresden", latitude: 51.0767496, longitude: 13.6321595})
MERGE (bruges)-[:NEXT]-&gt;(brussels)
MERGE (brussels)-[:NEXT]-&gt;(dresden)
MERGE (brussels)-[:NEXT]-&gt;(paris)
MERGE (bruges)-[:NEXT]-&gt;(paris)
MERGE (paris)-[:NEXT]-&gt;(dresden)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Finding paths and sort them by distance</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (a:City {name:'bruges'}), (b:City {name:'dresden'})
MATCH p=(a)-[*]-&gt;(b)
WITH collect(p) as paths
CALL apoc.spatial.sortPathsByDistance(paths) YIELD path, distance
RETURN path, distance</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_graph_refactoring"><a class="link" href="#_graph_refactoring">Graph Refactoring</a></h4>
<div class="paragraph">
<p>In order not to have to repeatedly geocode the same thing in multiple queries, especially
if the database will be used by many people, it might be a good idea to persist the results
in the database so that subsequent calls can use the saved results.</p>
</div>
<div class="paragraph">
<p>Geocode and persist the result</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (a:Place)
WHERE exists(a.address) AND NOT exists(a.latitude)
WITH a LIMIT 1000
CALL apoc.spatial.geocodeOnce(a.address) YIELD location
SET a.latitude = location.latitude
SET a.longitude = location.longitude</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that the above command only geocodes the first 1000 ‘Place’ nodes that have not already been geocoded.
This query can be run multiple times until all places are geocoded. Why would we want to do this?
Two good reasons:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The geocoding service is a public service that can throttle or blacklist sites that hit the service too heavily, so controlling how much we do is useful.</p>
</li>
<li>
<p>The transaction is updating the database, and it is wise not to update the database with too many things in the same transaction, to avoid using up too much memory. This trick will keep the memory usage very low.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Now make use of the results in distance queries</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH point({latitude: 48.8582532, longitude: 2.294287}) AS eiffel
MATCH (a:Place)
WHERE exists(a.latitude) AND exists(a.longitude)
WITH a, distance(point(a), eiffel) AS distance
WHERE distance &lt; 5000
RETURN a.name, distance
ORDER BY distance
LIMIT 100</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_combined_space_and_time_search"><a class="link" href="#_combined_space_and_time_search">Combined Space and Time search</a></h4>
<div class="paragraph">
<p>Combining spatial and date-time functions can allow for more complex queries:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH point({latitude: 48.8582532, longitude: 2.294287}) AS eiffel
MATCH (e:Event)
WHERE exists(e.address) AND exists(e.datetime)
CALL apoc.spatial.geocodeOnce(e.address) YIELD location
WITH e, location,
distance(point(location), eiffel) AS distance,
            (apoc.date.parse('2016-06-01 00:00:00','h') - apoc.date.parse(e.datetime,'h'))/24.0 AS days_before_due
WHERE distance &lt; 5000 AND days_before_due &lt; 14 AND apoc.date.parse(e.datetime,'h') &lt; apoc.date.parse('2016-06-01 00:00:00','h')
RETURN e.name AS event, e.datetime AS date,
location.description AS description, distance
ORDER BY distance</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_data_integration"><a class="link" href="#_data_integration">Data Integration</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_load_json"><a class="link" href="#_load_json">Load JSON</a></h3>
<div class="sect3">
<h4 id="_load_json_2"><a class="link" href="#_load_json_2">Load JSON</a></h4>
<div class="paragraph">
<p>Web APIs are a huge opportunity to access and integrate data from any sources with your graph.
Most of them provide the data as JSON.</p>
</div>
<div class="paragraph">
<p>With <code>apoc.load.json</code> you can retrieve data from URLs and turn it into map value(s) for Cypher to consume.
Cypher is pretty good at deconstructing nested documents with dot syntax, slices, <code>UNWIND</code> etc. so it is easy to turn nested data into graphs.</p>
</div>
<div class="paragraph">
<p>Sources with multiple JSON objects in a stream are also supported, like the <a href="https://dev.twitter.com/streaming/overview/processing">streaming Twitter format</a> or the Yelp Kaggle dataset.</p>
</div>
</div>
<div class="sect3">
<h4 id="_json_path"><a class="link" href="#_json_path">Json-Path</a></h4>
<div class="paragraph">
<p>Most of the <code>apoc.load.json</code> and <code>apoc.convert.*Json</code> procedures and functions now accept a json-path as last argument.</p>
</div>
<div class="paragraph">
<p>The json-path uses the <a href="https://github.com/jayway/JsonPath#operators">Java implementation by Jayway</a> of <a href="http://goessner.net/articles/JsonPath/">Stefan Gössners JSON-Path</a></p>
</div>
<div class="paragraph">
<p>Here is some syntax, there are more examples at the links above.</p>
</div>
<div class="paragraph">
<p><code>$.store.book[0].title</code></p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 2. Operators</caption>
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 66.6667%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Operator</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>$</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>The root element to query. This starts all path expressions.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>The current node being processed by a filter predicate.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>*</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Wildcard. Available anywhere a name or numeric are required.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>..</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Deep scan. Available anywhere a name is required.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>.&lt;name&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Dot-notated child</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>['&lt;name&gt;' (,'&lt;name&gt;')]</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Bracket-notated child or children</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>[&lt;number&gt; (,&lt;number&gt;)]</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Array index or indexes</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>[start:end]</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Array slice operator</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>[?(&lt;expression&gt;)]</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Filter expression. Expression must evaluate to a boolean value.</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>If used, this path is applied to the json and can be used to extract sub-documents and -values before handing the result to Cypher, resulting in shorter statements with complex nested JSON.</p>
</div>
<div class="paragraph">
<p>There is also a direct <code>apoc.json.path(json,path)</code> function.</p>
</div>
</div>
<div class="sect3">
<h4 id="_load_json_stackoverflow_example"><a class="link" href="#_load_json_stackoverflow_example">Load JSON StackOverflow Example</a></h4>
<div class="paragraph">
<p>There have been articles before about <a href="http://neo4j.com/blog/cypher-load-json-from-url/">loading JSON from Web-APIs like StackOverflow</a>.</p>
</div>
<div class="paragraph">
<p>With <code>apoc.load.json</code> it&#8217;s now very easy to load JSON data from any file or URL.</p>
</div>
<div class="paragraph">
<p>If the result is a JSON object is returned as a singular map.
Otherwise if it was an array is turned into a stream of maps.</p>
</div>
<div class="paragraph">
<p>The URL for retrieving the last questions and answers of the <a href="http://stackoverflow.com/questions/tagged/neo4j">neo4j tag</a> is this:</p>
</div>
<div class="paragraph">
<p><a href="https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf" class="bare">https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf</a></p>
</div>
<div class="paragraph">
<p>Now it can be used from within Cypher directly, let&#8217;s first introspect the data that is returned.</p>
</div>
<div class="listingblock">
<div class="title">JSON data from StackOverflow</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH "https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf" AS url
CALL apoc.load.json(url) YIELD value
UNWIND value.items AS item
RETURN item.title, item.owner, item.creation_date, keys(item)</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.load.json.so.png" alt="apoc.load.json.so">
</div>
</div>
<div class="listingblock">
<div class="title">Question authors from StackOverflow using json-path</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH "https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf" AS url
CALL apoc.load.json(url,'$.items.owner.name') YIELD value
RETURN name, count(*);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Combined with the cypher query from the original blog post it&#8217;s easy to create the full Neo4j graph of those entities.
We filter the original poster last, b/c deleted users have no <code>user_id</code> anymore.</p>
</div>
<div class="listingblock">
<div class="title">Graph data created via loading JSON from StackOverflow</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH "https://api.stackexchange.com/2.2/questions?pagesize=100&amp;order=desc&amp;sort=creation&amp;tagged=neo4j&amp;site=stackoverflow&amp;filter=!5-i6Zw8Y)4W7vpy91PMYsKM-k9yzEsSC1_Uxlf" AS url
CALL apoc.load.json(url) YIELD value
UNWIND value.items AS q
MERGE (question:Question {id:q.question_id}) ON CREATE
  SET question.title = q.title, question.share_link = q.share_link, question.favorite_count = q.favorite_count

FOREACH (tagName IN q.tags | MERGE (tag:Tag {name:tagName}) MERGE (question)-[:TAGGED]-&gt;(tag))
FOREACH (a IN q.answers |
   MERGE (question)&lt;-[:ANSWERS]-(answer:Answer {id:a.answer_id})
   MERGE (answerer:User {id:a.owner.user_id}) ON CREATE SET answerer.display_name = a.owner.display_name
   MERGE (answer)&lt;-[:PROVIDED]-(answerer)
)
WITH * WHERE NOT q.owner.user_id IS NULL
MERGE (owner:User {id:q.owner.user_id}) ON CREATE SET owner.display_name = q.owner.display_name
MERGE (owner)-[:ASKED]-&gt;(question)</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.load.json-so-result.png" alt="apoc.load.json so result">
</div>
</div>
</div>
<div class="sect3">
<h4 id="_load_json_from_twitter_with_additional_parameters"><a class="link" href="#_load_json_from_twitter_with_additional_parameters">Load JSON from Twitter (with additional parameters)</a></h4>
<div class="paragraph">
<p>With <code>apoc.load.jsonParams</code> you can send additional headers or payload with your JSON GET request, e.g. for the Twitter API:</p>
</div>
<div class="paragraph">
<p>Configure Bearer and Twitter Search Url token in <code>neo4j.conf</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre>apoc.static.twitter.bearer=XXXX
apoc.static.twitter.url=https://api.twitter.com/1.1/search/tweets.json?count=100&amp;result_type=recent&amp;lang=en&amp;q=</pre>
</div>
</div>
<div class="listingblock">
<div class="title">Twitter Search via Cypher</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.static.getAll("twitter") yield value AS twitter
CALL apoc.load.jsonParams(twitter.url + "oscon+OR+neo4j+OR+%23oscon+OR+%40neo4j",{Authorization:"Bearer "+twitter.bearer},null) yield value
UNWIND value.statuses as status
WITH status, status.user as u, status.entities as e
RETURN status.id, status.text, u.screen_name, [t IN e.hashtags | t.text] as tags, e.symbols, [m IN e.user_mentions | m.screen_name] as mentions, [u IN e.urls | u.expanded_url] as urls</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_geocoding_example"><a class="link" href="#_geocoding_example">GeoCoding Example</a></h4>
<div class="paragraph">
<p>Example for reverse geocoding and determining the route from one to another location.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH
        "21 rue Paul Bellamy 44000 NANTES FRANCE" AS fromAddr,
        "125 rue du docteur guichard 49000 ANGERS FRANCE" AS toAddr

call apoc.load.json("http://www.yournavigation.org/transport.php?url=http://nominatim.openstreetmap.org/search&amp;format=json&amp;q=" + replace(fromAddr, ' ', '%20')) YIELD value AS from

WITH from, toAddr  LIMIT 1

call apoc.load.json("http://www.yournavigation.org/transport.php?url=http://nominatim.openstreetmap.org/search&amp;format=json&amp;q=" + replace(toAddr, ' ', '%20')) YIELD value AS to

CALL apoc.load.json("https://router.project-osrm.org/viaroute?instructions=true&amp;alt=true&amp;z=17&amp;loc=" + from.lat + "," + from.lon + "&amp;loc=" + to.lat + "," + to.lon ) YIELD value AS doc

UNWIND doc.route_instructions as instruction

RETURN instruction</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_load_jdbc"><a class="link" href="#_load_jdbc">Load JDBC</a></h3>
<div class="sect3">
<h4 id="_overview_database_integration"><a class="link" href="#_overview_database_integration">Overview: Database Integration</a></h4>
<div class="paragraph">
<p>Data Integration is an important topic.
Reading data from relational databases to create and augment data models is a very helpful exercise.</p>
</div>
<div class="paragraph">
<p>With <code>apoc.load.jdbc</code> you can access any database that provides a JDBC driver, and execute queries whose results are turned into streams of rows.
Those rows can then be used to update or create graph structures.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 14.2857%;">
<col style="width: 14.2857%;">
<col style="width: 71.4286%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">type</th>
<th class="tableblock halign-left valign-top">qualified name</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.load.csv</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.csv('url',{config}) YIELD lineNo, list, map - load CSV fom URL as stream of values,
 config contains any of: {skip:1,limit:5,header:false,sep:'TAB',ignore:['tmp'],arraySep:';',mapping:{years:{type:'int',arraySep:'-',array:false,name:'age',ignore:false}}</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.load.ldap</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.load.ldap("key" or {connectionMap},{searchMap}) Load entries from an ldap source (yield entry)</p></td>
</tr>
</tbody>
</table>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc-jdbc-northwind-load.jpg" alt="apoc jdbc northwind load" width="600">
</div>
</div>
<div class="paragraph">
<p>To simplify the JDBC URL syntax and protect credentials, you can configure aliases in <code>conf/neo4j.conf</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>apoc.jdbc.myDB.url=jdbc:derby:derbyDB</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>CALL apoc.load.jdbc('jdbc:derby:derbyDB','PERSON')

becomes

CALL apoc.load.jdbc('myDB','PERSON')</pre>
</div>
</div>
<div class="paragraph">
<p>The 3rd value in the <code>apoc.jdbc.&lt;alias&gt;.url=</code> effectively defines an alias to be used in  <code>apoc.load.jdbc('&lt;alias&gt;',&#8230;&#8203;.</code></p>
</div>
</div>
<div class="sect3">
<h4 id="_mysql_example"><a class="link" href="#_mysql_example">MySQL Example</a></h4>
<div class="paragraph">
<p>Northwind is a common example set for relational databases, which is also covered in our import guides, e.g. <a play-topic='northwind graph'>:play northwind graph</a> in the Neo4j browser.</p>
</div>
<div class="sect4">
<h5 id="_mysql_northwind_data"><a class="link" href="#_mysql_northwind_data">MySQL Northwind Data</a></h5>
<div class="listingblock">
<div class="content">
<pre>select count(*) from products;
+----------+
| count(*) |
+----------+
|       77 |
+----------+
1 row in set (0,00 sec)</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>describe products;
+-----------------+---------------+------+-----+---------+----------------+
| Field           | Type          | Null | Key | Default | Extra          |
+-----------------+---------------+------+-----+---------+----------------+
| ProductID       | int(11)       | NO   | PRI | NULL    | auto_increment |
| ProductName     | varchar(40)   | NO   | MUL | NULL    |                |
| SupplierID      | int(11)       | YES  | MUL | NULL    |                |
| CategoryID      | int(11)       | YES  | MUL | NULL    |                |
| QuantityPerUnit | varchar(20)   | YES  |     | NULL    |                |
| UnitPrice       | decimal(10,4) | YES  |     | 0.0000  |                |
| UnitsInStock    | smallint(2)   | YES  |     | 0       |                |
| UnitsOnOrder    | smallint(2)   | YES  |     | 0       |                |
| ReorderLevel    | smallint(2)   | YES  |     | 0       |                |
| Discontinued    | bit(1)        | NO   |     | b'0'    |                |
+-----------------+---------------+------+-----+---------+----------------+
10 rows in set (0,00 sec)</pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_load_jdbc_examples"><a class="link" href="#_load_jdbc_examples">Load JDBC Examples</a></h4>
<div class="listingblock">
<div class="title">Load the JDBC driver</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">cypher CALL apoc.load.driver("com.mysql.jdbc.Driver");</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Count rows in products table</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">with "jdbc:mysql://localhost:3306/northwind?user=root" as url
cypher CALL apoc.load.jdbc(url,"products") YIELD row
RETURN count(*);</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>+----------+
| count(*) |
+----------+
| 77       |
+----------+
1 row
23 ms</pre>
</div>
</div>
<div class="listingblock">
<div class="title">Return row from products table</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">with "jdbc:mysql://localhost:3306/northwind?user=root" as url
cypher CALL apoc.load.jdbc(url,"products") YIELD row
RETURN row limit 1;</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>+--------------------------------------------------------------------------------+
| row                                                                            |
+--------------------------------------------------------------------------------+
| {UnitPrice -&gt; 18.0000, UnitsOnOrder -&gt; 0, CategoryID -&gt; 1, UnitsInStock -&gt; 39} |
+--------------------------------------------------------------------------------+
1 row
10 ms</pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc-load-jdbc.jpg" alt="apoc load jdbc" width="800">
</div>
</div>
</div>
<div class="sect3">
<h4 id="_load_jdbc_with_params_examples"><a class="link" href="#_load_jdbc_with_params_examples">Load JDBC with params Examples</a></h4>
<div class="listingblock">
<div class="content">
<pre>with "select firstname, lastname from employees where firstname like ? and lastname like ?" as sql
cypher call apoc.load.jdbcParams("northwind", sql, ['F%', '%w']) yield row
return row</pre>
</div>
</div>
<div class="paragraph">
<p>JDBC pretends positional "?" for parameters, so the third apoc parameter has to be an array with values coherent with that positions.
In case of 2 parameters, firstname and lastname ['firstname-position','lastname-position']</p>
</div>
</div>
<div class="sect3">
<h4 id="_load_data_in_transactional_batches"><a class="link" href="#_load_data_in_transactional_batches">Load data in transactional batches</a></h4>
<div class="paragraph">
<p>You can load data from jdbc and create/update the graph using the query results in batches (and in parallel).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.periodic.iterate('
call apoc.load.jdbc("jdbc:mysql://localhost:3306/northwind?user=root","company")',
'CREATE (p:Person) SET p += value', {batchSize:10000, parallel:true})
RETURN batches, total</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_cassandra_example"><a class="link" href="#_cassandra_example">Cassandra Example</a></h4>
<div class="paragraph">
<p>Setup Song database as initial dataset</p>
</div>
<div class="listingblock">
<div class="content">
<pre>curl -OL https://raw.githubusercontent.com/neo4j-contrib/neo4j-cassandra-connector/master/db_gen/playlist.cql
curl -OL https://raw.githubusercontent.com/neo4j-contrib/neo4j-cassandra-connector/master/db_gen/artists.csv
curl -OL https://raw.githubusercontent.com/neo4j-contrib/neo4j-cassandra-connector/master/db_gen/songs.csv
$CASSANDRA_HOME/bin/cassandra
$CASSANDRA_HOME/bin/cqlsh -f playlist.cql</pre>
</div>
</div>
<div class="paragraph">
<p>Download the <a href="https://github.com/adejanovski/cassandra-jdbc-wrapper#installing">Cassandra JDBC Wrapper</a>, and put it into your <code>$NEO4J_HOME/plugins</code> directory.
Add this config option to <code>$NEO4J_HOME/conf/neo4j.conf</code> to make it easier to interact with the cassandra instance.</p>
</div>
<div class="listingblock">
<div class="title">Add to conf/neo4j.conf</div>
<div class="content">
<pre>apoc.jdbc.cassandra_songs.url=jdbc:cassandra://localhost:9042/playlist</pre>
</div>
</div>
<div class="paragraph">
<p>Restart the server.</p>
</div>
<div class="paragraph">
<p>Now you can inspect the data in Cassandra with.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.load.jdbc('cassandra_songs','artists_by_first_letter') yield row
RETURN count(*);</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>╒════════╕
│count(*)│
╞════════╡
│3605    │
└────────┘</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.load.jdbc('cassandra_songs','artists_by_first_letter') yield row
RETURN row LIMIT 5;</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.load.jdbc('cassandra_songs','artists_by_first_letter') yield row
RETURN row.first_letter, row.artist LIMIT 5;</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>╒════════════════╤═══════════════════════════════╕
│row.first_letter│row.artist                     │
╞════════════════╪═══════════════════════════════╡
│C               │C.W. Stoneking                 │
├────────────────┼───────────────────────────────┤
│C               │CH2K                           │
├────────────────┼───────────────────────────────┤
│C               │CHARLIE HUNTER WITH LEON PARKER│
├────────────────┼───────────────────────────────┤
│C               │Calvin Harris                  │
├────────────────┼───────────────────────────────┤
│C               │Camané                         │
└────────────────┴───────────────────────────────┘</pre>
</div>
</div>
<div class="paragraph">
<p>Let&#8217;s create some graph data, we have a look at the track_by_artist table, which contains about 60k records.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.load.jdbc('cassandra_songs','track_by_artist') yield row RETURN count(*);</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.load.jdbc('cassandra_songs','track_by_artist') yield row
RETURN row LIMIT 5;</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.load.jdbc('cassandra_songs','track_by_artist') yield row
RETURN row.track_id, row.track_length_in_seconds, row.track, row.music_file, row.genre, row.artist, row.starred LIMIT 2;</code></pre>
</div>
</div>
<div class="listingblock small">
<div class="content">
<pre>╒════════════════════════════════════╤══════╤════════════════╤══════════════════╤═════════╤════════════════════════════╤═══════════╕
│row.track_id                        │length│row.track       │row.music_file    │row.genre│row.artist                  │row.starred│
╞════════════════════════════════════╪══════╪════════════════╪══════════════════╪═════════╪════════════════════════════╪═══════════╡
│c0693b1e-0eaa-4e81-b23f-b083db303842│219   │1913 Massacre   │TRYKHMD128F934154C│folk     │Woody Guthrie &amp; Jack Elliott│false      │
├────────────────────────────────────┼──────┼────────────────┼──────────────────┼─────────┼────────────────────────────┼───────────┤
│7d114937-0bc7-41c7-8e0c-94b5654ac77f│178   │Alabammy Bound  │TRMQLPV128F934152B│folk     │Woody Guthrie &amp; Jack Elliott│false      │
└────────────────────────────────────┴──────┴────────────────┴──────────────────┴─────────┴────────────────────────────┴───────────┘</pre>
</div>
</div>
<div class="paragraph">
<p>Let&#8217;s create some indexes and constraints, note that other indexes and constraints will be dropped by this.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.schema.assert(
  {Track:['title','length']},
  {Artist:['name'],Track:['id'],Genre:['name']});</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>╒════════════╤═══════╤══════╤═══════╕
│label       │key    │unique│action │
╞════════════╪═══════╪══════╪═══════╡
│Track       │title  │false │CREATED│
├────────────┼───────┼──────┼───────┤
│Track       │length │false │CREATED│
├────────────┼───────┼──────┼───────┤
│Artist      │name   │true  │CREATED│
├────────────┼───────┼──────┼───────┤
│Genre       │name   │true  │CREATED│
├────────────┼───────┼──────┼───────┤
│Track       │id     │true  │CREATED│
└────────────┴───────┴──────┴───────┘</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.load.jdbc('cassandra_songs','track_by_artist') yield row
MERGE (a:Artist {name:row.artist})
MERGE (g:Genre {name:row.genre})
CREATE (t:Track {id:toString(row.track_id), title:row.track, length:row.track_length_in_seconds})
CREATE (a)-[:PERFORMED]-&gt;(t)
CREATE (t)-[:GENRE]-&gt;(g);</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>Added 63213 labels, created 63213 nodes, set 182413 properties, created 119200 relationships, statement executed in 40076 ms.</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_support_for_hive_with_kerberos_auth"><a class="link" href="#_support_for_hive_with_kerberos_auth">Support for Hive with Kerberos Auth</a></h4>
<div class="paragraph">
<p>Support for Hive especially with Kerberos is more involved.</p>
</div>
<div class="paragraph">
<p>First of all the required configuration is more detailed, make sure to get this information:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>kerberos user / password</p>
</li>
<li>
<p>kerberos realm / kdc</p>
</li>
<li>
<p>hive hostname + port (10000)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Create this <code>login.conf</code> file at a known location:</p>
</div>
<div class="listingblock">
<div class="title">login.conf</div>
<div class="content">
<pre>KerberosClient {
  com.sun.security.auth.module.Krb5LoginModule required
  debug=true debugNative=true;
};</pre>
</div>
</div>
<div class="paragraph">
<p>Add these options to your <code>conf/neo4j.conf</code></p>
</div>
<div class="listingblock">
<div class="title">neo4j.conf</div>
<div class="content">
<pre>dbms.jvm.additional=-Djava.security.auth.login.config=/path/to/login.conf
dbms.jvm.additional=-Djava.security.auth.login.config.client=KerberosClient
dbms.jvm.additional=-Djava.security.krb5.realm=KRB.REALM.COM
dbms.jvm.additional=-Djava.security.krb5.kdc=krb-kdc.host.com</pre>
</div>
</div>
<div class="paragraph">
<p>Unlike other JDBC drivers, Hive comes with a bunch of dependencies, you can download these from the Hadoop providers</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://www.cloudera.com/downloads/connectors/hive/jdbc/2-5-20.html" target="_blank">Cloudera Hive Drivers</a></p>
</li>
<li>
<p><a href="https://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.6.3/bk_data-access/content/hive-jdbc-odbc-drivers.html" target="_blank">Hortonworks Hive Drivers</a></p>
</li>
<li>
<p><a href="https://cwiki.apache.org/confluence/display/Hive/HiveServer2+Clients#HiveServer2Clients-JDBC" target="_blank">Apache Hive Driver</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>or grab them from <a href="https://search.maven.org" target="_blank">maven central</a>.</p>
</div>
<div class="paragraph">
<p>The versions might vary, use what comes with your Hive driver.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>hadoop-common-2.7.3.2.6.1.0-129.jar</p>
</li>
<li>
<p>hive-exec-1.2.1000.2.6.1.0-129.jar</p>
</li>
<li>
<p>hive-jdbc-1.2.1000.2.6.1.0-129.jar</p>
</li>
<li>
<p>hive-metastore-1.2.1000.2.6.1.0-129.jar</p>
</li>
<li>
<p>hive-service-1.2.1000.2.6.1.0-129.jar</p>
</li>
<li>
<p>httpclient-4.4.jar</p>
</li>
<li>
<p>httpcore-4.4.jar</p>
</li>
<li>
<p>libfb303-0.9.2.jar</p>
</li>
<li>
<p>libthrift-0.9.3.jar</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Now you can use a JDBC URL like this from APOC.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
This has no newlines, it&#8217;s just wrapped because it is too long.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p><code>jdbc:hive2://username%40krb-realm:password@hive-hostname:10000/default;principal=hive/hostname@krb-realm;auth=kerberos;kerberosAuthType=fromSubject</code></p>
</div>
<div class="paragraph">
<p>And then call:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH 'jdbc:hive2://username%40krb-realm:password@hive-hostname:10000/default;principal=hive/hostname@krb-realm;auth=kerberos;kerberosAuthType=fromSubject' AS url
CALL apoc.load.jdbc(url,'PRODUCTS') YIELD row
RETURN row.name, row.price;</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also set it in your <code>conf/neo4j.conf</code> as a key:</p>
</div>
<div class="listingblock">
<div class="title">neo4j.conf</div>
<div class="content">
<pre>apoc.jdbc.my-hive.url=jdbc:hive2://username%40krb-realm:password@hive-hostname:10000/default;principal=hive/hostname@krb-realm;auth=kerberos;kerberosAuthType=fromSubject</pre>
</div>
</div>
<div class="paragraph">
<p>And then use the more compact call:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.load.jdbc('my-hive','SELECT * PRODUCTS');</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_load_jdbc_resources"><a class="link" href="#_load_jdbc_resources">LOAD JDBC - Resources</a></h4>
<div class="paragraph">
<p>To use other JDBC drivers use these download links and JDBC URL.
Put the JDBC driver into the <code>$NEO4J_HOME/plugins</code> directory and configure the JDBC-URL in <code>$NEO4J_HOME/conf/neo4j.conf</code> with <code>apoc.jdbc.&lt;alias&gt;.url=&lt;jdbc-url&gt;</code></p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 20%;">
<col style="width: 60%;">
<col style="width: 20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Database</th>
<th class="tableblock halign-left valign-top">JDBC-URL</th>
<th class="tableblock halign-left valign-top"> Driver Source</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>MySQL</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>jdbc:mysql://&lt;hostname&gt;:&lt;port/3306&gt;/&lt;database&gt;?user=&lt;user&gt;&amp;password=&lt;pass&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><a href="http://dev.mysql.com/downloads/connector/j/">MySQL Driver</a></p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Postgres</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>jdbc:postgresql://&lt;hostname&gt;/&lt;database&gt;?user=&lt;user&gt;&amp;password=&lt;pass&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><a href="https://jdbc.postgresql.org/download.html">PostgresSQL JDBC Driver</a></p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Oracle</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>jdbc:oracle:thin:&lt;user&gt;/&lt;pass&gt;@&lt;host&gt;:&lt;port&gt;/&lt;service_name&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><a href="http://www.oracle.com/technetwork/database/features/jdbc/index.html">Oracle JDBC Driver</a></p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>MS SQLServer</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>jdbc:sqlserver://;servername=&lt;servername&gt;;databaseName=&lt;database&gt;;user=&lt;user&gt;;password=&lt;pass&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><a href="https://www.microsoft.com/en-us/download/details.aspx?id=11774">SQLServer Driver</a></p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>IBM DB2</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>jdbc:db2://&lt;host&gt;:&lt;port/5021&gt;/&lt;database&gt;:user=&lt;user&gt;;password=&lt;pass&gt;;</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><a href="http://www-01.ibm.com/support/docview.wss?uid=swg21363866">DB2 Driver</a></p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Derby</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>jdbc:derby:derbyDB</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Included in JDK6-8</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Cassandra</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>jdbc:cassandra://&lt;host&gt;:&lt;port/9042&gt;/&lt;database&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><a href="https://github.com/adejanovski/cassandra-jdbc-wrapper#installing">Cassandra JDBC Wrapper</a></p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>SAP Hana</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>jdbc:sap://&lt;host&gt;:&lt;port/39015&gt;/?user=&lt;user&gt;&amp;password=&lt;pass&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><a href="https://www.sap.com/developer/topics/sap-hana-express.html">SAP Hana ngdbc Driver</a></p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Apache Hive (w/ Kerberos)</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>jdbc:hive2://username%40krb-realm:password@hostname:10000/default;principal=hive/hostname@krb-realm;auth=kerberos;kerberosAuthType=fromSubject</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><a href="https://cwiki.apache.org/confluence/display/Hive/HiveServer2+Clients#HiveServer2Clients-JDBC">Apache Hive Driver</a> <a href="https://www.cloudera.com/downloads/connectors/hive/jdbc/2-5-20.html">(Cloudera)</a> <a href="https://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.6.3/bk_data-access/content/hive-jdbc-odbc-drivers.html">(Hortonworks)</a>
 There are several jars (hadoop-common-xxx.jar hive-exec-xxx.jar hive-jdbc-xxx.jar hive-metastore-xxx.jar hive-service-xxx.jar httpclient-4.4.jar httpcore-4.4.jar libfb303-0.9.2.jar libthrift-0.9.3.jar)</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>There are a number of blog posts / examples that details usage of apoc.load.jdbc</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://jesusbarrasa.wordpress.com/2016/09/30/quickgraph4-explore-your-browser-history-in-neo4j/">Explore your browser history in Neo4j</a></p>
</li>
<li>
<p><a href="https://blog.knoldus.com/2016/09/12/neo4j-with-scala-migrate-data-from-other-database-to-neo4j/">Neo4j With Scala : Migrate Data From Other Database to Neo4j</a>
*</p>
</li>
<li>
<p><a href="https://neo4j.com/blog/apoc-database-integration-import-export-cypher/">APOC: Database Integration, Import and Export with Awesome Procedures On Cypher</a></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_streaming_data_to_gephi"><a class="link" href="#_streaming_data_to_gephi">Streaming Data to Gephi</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 14.2857%;">
<col style="width: 14.2857%;">
<col style="width: 71.4286%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">type</th>
<th class="tableblock halign-left valign-top">qualified name</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.gephi.add</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.gephi.add(url-or-key, workspace, data, weightproperty) | streams passed in data to Gephi</p></td>
</tr>
</tbody>
</table>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc-gephi.gif" alt="apoc gephi" width="800">
</div>
</div>
<div class="sect4">
<h5 id="_notes"><a class="link" href="#_notes">Notes</a></h5>
<div class="paragraph">
<p>Gephi has a <a href="https://marketplace.gephi.org/plugin/graph-streaming/">streaming plugin</a>, that can provide and accept <a href="https://github.com/gephi/gephi/wiki/GraphStreaming#Gephi_as_Master">JSON-graph-data</a> in a streaming fashion.</p>
</div>
<div class="paragraph">
<p>Make sure to install the plugin firsrt and activate it for your workspace (there is a new "Streaming"-tab besides "Layout"), right-click "Master"&#8594;"start" to start the server.</p>
</div>
<div class="paragraph">
<p>You can provide your workspace name (you might want to rename it before you start thes streaming), otherwise it defaults to <code>workspace0</code></p>
</div>
<div class="paragraph">
<p>The default Gephi-URL is <a href="http://localhost:8080" class="bare">http://localhost:8080</a>, resulting in <code><a href="http://localhost:8080/workspace0?operation=updateGraph" class="bare">http://localhost:8080/workspace0?operation=updateGraph</a></code></p>
</div>
<div class="paragraph">
<p>You can also configure it in <code>conf/neo4j.conf</code> via  <code>apoc.gephi.url=url</code> or <code>apoc.gephi.&lt;key&gt;.url=url</code></p>
</div>
</div>
<div class="sect4">
<h5 id="_example"><a class="link" href="#_example">Example</a></h5>
<div class="paragraph">
<p>You can export your graph as an unweighted network.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">match path = (:Person)-[:ACTED_IN]-&gt;(:Movie)
WITH path LIMIT 1000
with collect(path) as paths
call apoc.gephi.add(null,'workspace0', paths) yield nodes, relationships, time
return nodes, relationships, time</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can export your graph as a weighted network, by specifying the property of a relationship, that holds the weight value.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">match path = (:Person)-[r:ACTED_IN]-&gt;(:Movie) where exists r.weightproperty
WITH path LIMIT 1000
with collect(path) as paths
call apoc.gephi.add(null,'workspace0', paths, 'weightproperty') yield nodes, relationships, time
return nodes, relationships, time</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also export with your graph other properties of your nodes and/or relationship by adding an optional array with the property names you want to export.
Example for exporting <code>birthYear</code> and <code>role</code> property.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">match path = (:Person)-[r:ACTED_IN]-&gt;(:Movie) where exists r.weightproperty
WITH path LIMIT 1000
with collect(path) as paths
call apoc.gephi.add(null,'workspace0', paths, 'weightproperty',['birthYear', 'role']) yield nodes, relationships, time
return nodes, relationships, time</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_format"><a class="link" href="#_format">Format</a></h4>
<div class="paragraph">
<p>We send all nodes and relationships of the passed in data convert into individual Gephi-Streaming JSON fragements, separated by <code>\r\n</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-javascript" data-lang="javascript">{"an":{"123":{"TYPE":"Person:Actor","label":"Tom Hanks",                           x:333,y:222,r:0.1,g:0.3,b:0.5}}}\r\n
{"an":{"345":{"TYPE":"Movie","label":"Forrest Gump",                               x:234,y:122,r:0.2,g:0.2,b:0.7}}}\r\n
{"ae":{"3344":{"TYPE":"ACTED_IN","label":"Tom Hanks",source:"123",target:"345","directed":true,"weight":1.0,r:0.1,g:0.3,b:0.5}}}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_specifics_details"><a class="link" href="#_specifics_details">Specifics Details</a></h4>
<div class="paragraph">
<p>Gephi doesn&#8217;t render the graph data unless you also provide x,y coordinates in the payload, so we just send random ones within a 1000x1000 grid.</p>
</div>
<div class="paragraph">
<p>We also generate colors per label combination and relationship-type, both of which are also transferred as <code>TYPE</code> property.</p>
</div>
<div class="paragraph">
<p>You can have your weight property stored as a number (integer,float) or a string. If the weight property is invalid or null, it will use the default 1.0 value.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_elasticsearch_integration"><a class="link" href="#_elasticsearch_integration">ElasticSearch Integration</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 14.2857%;">
<col style="width: 14.2857%;">
<col style="width: 71.4286%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">type</th>
<th class="tableblock halign-left valign-top">qualified name</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.stats</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.stats(host-url-Key) - elastic search statistics</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.get</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.get(host-or-port,index-or-null,type-or-null,id-or-null,query-or-null,payload-or-null) yield value - perform a GET operation on elastic search</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.query</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.query(host-or-port,index-or-null,type-or-null,query-or-null,payload-or-null) yield value - perform a SEARCH operation on elastic search</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.getRaw</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.getRaw(host-or-port,path,payload-or-null) yield value - perform a raw GET operation on elastic search</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.postRaw</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.postRaw(host-or-port,path,payload-or-null) yield value - perform a raw POST operation on elastic search</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.post</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.post(host-or-port,index-or-null,type-or-null,query-or-null,payload-or-null) yield value - perform a POST operation on elastic search</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.put</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.es.put(host-or-port,index-or-null,type-or-null,id-or-null,query-or-null,payload-or-null) yield value - perform a PUT operation on elastic search</p></td>
</tr>
</tbody>
</table>
<div class="sect3">
<h4 id="_example_2"><a class="link" href="#_example_2">Example</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.es.post("localhost","tweets","users","1",null,{name:"Chris"})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.es.get("localhost","tweets","users","1",null,null)</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.es.stats("localhost")</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="http://i.imgur.com/qHAj9ma.png" alt="qHAj9ma" width="500">
</div>
</div>
<div class="sect4">
<h5 id="_pagination"><a class="link" href="#_pagination">Pagination</a></h5>
<div class="paragraph">
<p>To use the pagination feature of Elasticsearch you have to follow these steps:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Call <strong>apoc.es.query</strong> to get the first chunk of data and obtain also the scroll_id (in order to enable the pagination).</p>
</li>
<li>
<p>Do your merge/create etc. operations with the first N hits</p>
</li>
<li>
<p>Use the <strong>range(start,end,step)</strong> function to repeat a second call to get all the other chunks until the end. For example, if you have 1000 documents and you want to retrieve 10 documents for each request, you cand do <strong>range(11,1000,10)</strong>. You start from 11 because the first 10 documents are already processed. If you don&#8217;t know the exact upper bound (the total size of your documents) you can set a number that is bigger than the real total size.</p>
</li>
<li>
<p>The second call to repeat is <strong>apoc.es.get</strong>. Remember to set the <strong>scroll_id</strong> as a parameter.</p>
</li>
<li>
<p>Then process the result of each chunk of data as the first one.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Here an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">// It's important to create an index to improve performance
CREATE INDEX ON :Document(id)
// First query: get first chunk of data + the scroll_id for pagination
CALL apoc.es.query('localhost','test-index','test-type','name:Neo4j&amp;size=1&amp;scroll=5m',null) yield value with value._scroll_id as scrollId, value.hits.hits as hits
// Do something with hits
UNWIND hits as hit
// Here we simply create a document and a relation to a company
MERGE (doc:Document {id: hit._id, description: hit._source.description, name: hit._source.name})
MERGE (company:Company {name: hit._source.company})
MERGE (doc)-[:IS_FROM]-&gt;(company)
// Then call for the other docs and use the scrollId value from previous query
// Use a range to count our chunk of data (i.e. i want to get chunks from 2 to 10)
WITH range(2,10,1) as list, scrollId
UNWIND list as count
CALL apoc.es.get("localhost","_search","scroll",null,{scroll:"5m",scroll_id:scrollId},null) yield value with value._scoll_id as scrollId, value.hits.hits as nextHits
// Again, do something with hits
UNWIND nextHits as hit
MERGE (doc:Document {id: hit._id, description: hit._source.description, name: hit._source.name})
MERGE (company:Company {name: hit._source.company})
MERGE (doc)-[:IS_FROM]-&gt;(company) return scrollId, doc, company</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example was tested on a Mac Book Pro with 16GB of RAM. Loading 20000 documents from ES to Neo4j (100 documents for each request) took 1 minute.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_general_structure_and_parameters"><a class="link" href="#_general_structure_and_parameters">General Structure and Parameters</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.es.post(host-or-port,index-or-null,type-or-null,id-or-null,query-or-null,payload-or-null) yield value

// GET/PUT/POST url/index/type/id?query -d payload</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_host_or_port_parameter"><a class="link" href="#_host_or_port_parameter">host or port parameter</a></h5>
<div class="paragraph">
<p>The parameter can be a direct host or url, or an entry to be lookup up in neo4j.conf</p>
</div>
<div class="ulist">
<ul>
<li>
<p>host</p>
</li>
<li>
<p>host:port</p>
</li>
<li>
<p><a href="http://host:port" class="bare">http://host:port</a></p>
</li>
<li>
<p>lookup via key to apoc.es.&lt;key&gt;.url</p>
</li>
<li>
<p>lookup via key apoc.es.&lt;key&gt;.host</p>
</li>
<li>
<p>lookup apoc.es.url</p>
</li>
<li>
<p>lookup apoc.es.host</p>
</li>
</ul>
</div>
</div>
<div class="sect4">
<h5 id="_index_parameter"><a class="link" href="#_index_parameter">index parameter</a></h5>
<div class="paragraph">
<p>Main ES index, will be sent directly, if null then "_all" multiple indexes can be separated by comma in the string.</p>
</div>
</div>
<div class="sect4">
<h5 id="_type_parameter"><a class="link" href="#_type_parameter">type parameter</a></h5>
<div class="paragraph">
<p>Document type, will be sent directly, if null then "_all" multiple types can be separated by comma in the string.</p>
</div>
</div>
<div class="sect4">
<h5 id="_id_parameter"><a class="link" href="#_id_parameter">id parameter</a></h5>
<div class="paragraph">
<p>Document id, will be left off when null.</p>
</div>
</div>
<div class="sect4">
<h5 id="_query_parameter"><a class="link" href="#_query_parameter">query parameter</a></h5>
<div class="paragraph">
<p>Query can be a map which is turned into a query string, a direct string or null then it is left off.</p>
</div>
</div>
<div class="sect4">
<h5 id="_payload_parameter"><a class="link" href="#_payload_parameter">payload parameter</a></h5>
<div class="paragraph">
<p>Payload can be a <strong>map</strong> which will be turned into a json payload or a string which will be sent directly or null.</p>
</div>
</div>
<div class="sect4">
<h5 id="_results"><a class="link" href="#_results">Results</a></h5>
<div class="paragraph">
<p>Results are stream of map in value.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_load_xml"><a class="link" href="#_load_xml">Load XML</a></h3>
<div class="sect3">
<h4 id="_load_xml_introduction"><a class="link" href="#_load_xml_introduction">Load XML Introduction</a></h4>
<div class="paragraph">
<p>Many existing (enterprise) applications, endpoints and files use XML as data exchange format.</p>
</div>
<div class="paragraph">
<p>To make these datastructures available to Cypher, you can use <code>apoc.load.xml</code>.
It takes a file or http URL and parses the XML into a map datastructure.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
in previous releases we&#8217;ve had <code>apoc.load.xmlSimple</code>. This is now deprecated and got superseeded by
<code>apoc.load.xml(url, [xPath], [config], true)</code>.Simple XML Format
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>See the following usage-examples for the procedures.</p>
</div>
</div>
<div class="sect3">
<h4 id="_example_file"><a class="link" href="#_example_file">Example File</a></h4>
<div class="paragraph">
<p>"How do you access XML doc attributes in children fields ?"</p>
</div>
<div class="paragraph">
<p>(Thanks Nicolas Rouyer)</p>
</div>
<div class="paragraph">
<p>For example, if my XML file is the example <a href="https://msdn.microsoft.com/en-us/library/ms762271%28v=vs.85%29.aspx">book.xml provided by Microsoft</a>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0"?&gt;
&lt;catalog&gt;
   &lt;book id="bk101"&gt;
      &lt;author&gt;Gambardella, Matthew&lt;/author&gt;
      &lt;title&gt;XML Developer's Guide&lt;/title&gt;
      &lt;genre&gt;Computer&lt;/genre&gt;
      &lt;price&gt;44.95&lt;/price&gt;
      &lt;publish_date&gt;2000-10-01&lt;/publish_date&gt;
      &lt;description&gt;An in-depth look at creating applications
      with XML.&lt;/description&gt;
   &lt;/book&gt;
   &lt;book id="bk102"&gt;
      &lt;author&gt;Ralls, Kim&lt;/author&gt;
      &lt;title&gt;Midnight Rain&lt;/title&gt;
      &lt;genre&gt;Fantasy&lt;/genre&gt;
      &lt;price&gt;5.95&lt;/price&gt;
      &lt;publish_date&gt;2000-12-16&lt;/publish_date&gt;
      &lt;description&gt;A former architect battles corporate zombies,
...</code></pre>
</div>
</div>
<div class="paragraph">
<p>We have the file here, <a href="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.3/src/test/resources/books.xml">on GitHub</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="_simple_xml_format"><a class="link" href="#_simple_xml_format">Simple XML Format</a></h4>
<div class="paragraph">
<p>In a simpler XML representation, each type of children gets it&#8217;s own entry within the parent map.
The element-type as key is prefixed with "_" to prevent collisions with attributes.</p>
</div>
<div class="paragraph">
<p>If there is a single element, then the entry will just have that element as value, not a collection.
If there is more than one element there will be a list of values.</p>
</div>
<div class="paragraph">
<p>Each child will still have its <code>_type</code> field to discern them.</p>
</div>
<div class="paragraph">
<p>Here is the example file from above loaded with <code>apoc.load.xmlSimple</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.load.xml("https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.3/src/test/resources/books.xml", '', {}, true)</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-javascript" data-lang="javascript">{_type: "catalog", _book: [
  {_type: "book", id: "bk101",
    _author: [{_type: "author", _text: "Gambardella, Matthew"},{_type: author, _text: "Arciniegas, Fabio"}],
    _title: {_type: "title", _text: "XML Developer's Guide"},
    _genre: {_type: "genre", _text: "Computer"},
    _price: {_type: "price", _text: "44.95"},
    _publish_date: {_type: "publish_date", _text: "2000-10-01"},
    _description: {_type: description, _text: An in-depth look at creating applications ....</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_simple_xml_examples"><a class="link" href="#_simple_xml_examples">Simple XML Examples</a></h5>
<div class="listingblock">
<div class="title">Example 1</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH "https://maps.googleapis.com/maps/api/directions/xml?origin=Mertens%20en%20Torfsstraat%2046,%202018%20Antwerpen&amp;destination=Rubensstraat%2010,%202300%20Turnhout&amp;sensor=false&amp;mode=bicycling&amp;alternatives=false&amp;key=AIzaSyAPPIXGudOyHD_KAa2f_1l_QVNbsd_pMQs" AS url
CALL apoc.load.xmlSimple(url) YIELD value
RETURN value._route._leg._distance._value, keys(value), keys(value._route), keys(value._route._leg), keys(value._route._leg._distance._value)</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.load.xmlSimple.ex1.png" alt="apoc.load.xmlSimple.ex1" width="800">
</div>
</div>
<div class="listingblock">
<div class="title">Example 2</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">WITH "https://maps.googleapis.com/maps/api/directions/xml?origin=Mertens%20en%20Torfsstraat%2046,%202018%20Antwerpen&amp;destination=Rubensstraat%2010,%202300%20Turnhout&amp;sensor=false&amp;mode=bicycling&amp;alternatives=false&amp;key=AIzaSyAPPIXGudOyHD_KAa2f_1l_QVNbsd_pMQs" AS url
CALL apoc.load.xmlSimple(url) YIELD value
UNWIND keys(value) AS key
RETURN key, apoc.meta.type(value[key]);</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.load.xmlSimple.ex2.png" alt="apoc.load.xmlSimple.ex2" width="800">
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_xpath"><a class="link" href="#_xpath">xPath</a></h4>
<div class="paragraph">
<p>It&#8217;s possible to define a xPath (optional) to selecting nodes from the XML document.</p>
</div>
<div class="sect4">
<h5 id="_xpath_example"><a class="link" href="#_xpath_example">xPath Example</a></h5>
<div class="paragraph">
<p>From the Microsoft&#8217;s book.xml file we can get only the books that have as <code>genre</code> Computer</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.load.xml("https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.1/src/test/resources/books.xml", '/catalog/book[genre=\"Computer\"]') yield value as book
WITH book.id as id, [attr IN book._children WHERE attr._type IN ['title','price'] | attr._text] as pairs
RETURN id, pairs[0] as title, pairs[1] as price</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.load.xml.xpath.png" alt="apoc.load.xml.xpath" width="800">
</div>
</div>
<div class="paragraph">
<p>In this case we return only <code>id</code>, <code>title</code> and <code>prize</code> but we can return any other elements</p>
</div>
<div class="paragraph">
<p>We can also return just a single specific element.
For example the <code>author</code> of the book with <code>id = bg102</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.load.xml('https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.1/src/test/resources/books.xml', '/catalog/book[@id="bk102"]/author') yield value as result
WITH result._text as author
RETURN author</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.load.xml.xpath2.png" alt="apoc.load.xml.xpath2" width="800">
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_load_xml_and_introspect"><a class="link" href="#_load_xml_and_introspect">Load XML and Introspect</a></h4>
<div class="paragraph">
<p>Let&#8217;s just load it and see what it looks like.
It&#8217;s returned as value map with nested <code>_type</code> and <code>_children</code> fields, per group of elements.
Attributes are turned into map-entries.
And each element into their own little map with <code>_type</code>, attributes and <code>_children</code> if applicable.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.load.xml("https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.3/src/test/resources/books.xml")</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-javascript" data-lang="javascript">{_type: catalog, _children: [
  {_type: book, id: bk101, _children: [
    {_type: author, _text: Gambardella, Matthew},
    {_type: title, _text: XML Developer's Guide},
    {_type: genre, _text: Computer},
    {_type: price, _text: 44.95},
    {_type: publish_date, _text: 2000-10-01},
    {_type: description, _text: An in-depth look at creating applications ....</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_for_each_book_how_do_i_access_book_id"><a class="link" href="#_for_each_book_how_do_i_access_book_id">For each book, how do I access book id ?</a></h5>
<div class="paragraph">
<p>You can access attributes per element directly.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.load.xml("https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.3/src/test/resources/books.xml") yield value as catalog
UNWIND catalog._children as book
RETURN book.id</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>╒═══════╕
│book.id│
╞═══════╡
│bk101  │
├───────┤
│bk102  │</pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_for_each_book_how_do_i_access_book_author_and_title"><a class="link" href="#_for_each_book_how_do_i_access_book_author_and_title">For each book, how do I access book author and title ?</a></h5>
<div class="sect5">
<h6 id="_filter_into_collection"><a class="link" href="#_filter_into_collection">Filter into collection</a></h6>
<div class="paragraph">
<p>You have to filter over the sub-elements  in the <code>_childrens</code> array in this case.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.load.xml("https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.3/src/test/resources/books.xml") yield value as catalog
UNWIND catalog._children as book
RETURN book.id, [attr IN book._children WHERE attr._type IN ['author','title'] | [attr._type, attr._text]] as pairs</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>╒═══════╤════════════════════════════════════════════════════════════════════════╕
│book.id│pairs                                                                   │
╞═══════╪════════════════════════════════════════════════════════════════════════╡
│bk101  │[[author, Gambardella, Matthew], [title, XML Developer's Guide]]        │
├───────┼────────────────────────────────────────────────────────────────────────┤
│bk102  │[[author, Ralls, Kim], [title, Midnight Rain]]                          │</pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="_how_do_i_return_collection_elements"><a class="link" href="#_how_do_i_return_collection_elements">How do I return collection elements?</a></h6>
<div class="paragraph">
<p>This is not too nice, we could also just have returned the values and then grabbed them out of the list, but that relies on element-order.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.load.xml("https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.3/src/test/resources/books.xml") yield value as catalog
UNWIND catalog._children as book
WITH book.id as id, [attr IN book._children WHERE attr._type IN ['author','title'] | attr._text] as pairs
RETURN id, pairs[0] as author, pairs[1] as title</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>╒═════╤════════════════════╤══════════════════════════════╕
│id   │author              │title                         │
╞═════╪════════════════════╪══════════════════════════════╡
│bk101│Gambardella, Matthew│XML Developer's Guide         │
├─────┼────────────────────┼──────────────────────────────┤
│bk102│Ralls, Kim          │Midnight Rain                 │</pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_extracting_datastructures"><a class="link" href="#_extracting_datastructures">Extracting Datastructures</a></h4>
<div class="sect4">
<h5 id="_turn_pairs_into_map"><a class="link" href="#_turn_pairs_into_map">Turn Pairs into Map</a></h5>
<div class="paragraph">
<p>So better is to turn them into a map with <code>apoc.map.fromPairs</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.load.xml("https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.3/src/test/resources/books.xml") yield value as catalog
UNWIND catalog._children as book
WITH book.id as id, [attr IN book._children WHERE attr._type IN ['author','title'] | [attr._type, attr._text]] as pairs
CALL apoc.map.fromPairs(pairs) yield value
RETURN id, value</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>╒═════╤════════════════════════════════════════════════════════════════════╕
│id   │value                                                               │
╞═════╪════════════════════════════════════════════════════════════════════╡
│bk101│{author: Gambardella, Matthew, title: XML Developer's Guide}        │
├─────┼────────────────────────────────────────────────────────────────────┤
│bk102│{author: Ralls, Kim, title: Midnight Rain}                          │
├─────┼────────────────────────────────────────────────────────────────────┤
│bk103│{author: Corets, Eva, title: Maeve Ascendant}                       │</pre>
</div>
</div>
<div class="sect5">
<h6 id="_return_individual_columns"><a class="link" href="#_return_individual_columns">Return individual Columns</a></h6>
<div class="paragraph">
<p>And now we can cleanly access the attributes from the map.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.load.xml("https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.3/src/test/resources/books.xml") yield value as catalog
UNWIND catalog._children as book
WITH book.id as id, [attr IN book._children WHERE attr._type IN ['author','title'] | [attr._type, attr._text]] as pairs
CALL apoc.map.fromPairs(pairs) yield value
RETURN id, value.author, value.title</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>╒═════╤════════════════════╤══════════════════════════════╕
│id   │value.author        │value.title                   │
╞═════╪════════════════════╪══════════════════════════════╡
│bk101│Gambardella, Matthew│XML Developer's Guide         │
├─────┼────────────────────┼──────────────────────────────┤
│bk102│Ralls, Kim          │Midnight Rain                 │
├─────┼────────────────────┼──────────────────────────────┤
│bk103│Corets, Eva         │Maeve Ascendant               │</pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_import_xml_directly"><a class="link" href="#_import_xml_directly">import xml directly</a></h4>
<div class="paragraph">
<p>In case you don&#8217;t want to transform your xml (like you do with <code>apoc.load.xml/apoc.load.xmlSimple</code> before you create nodes and relationships and you want to have a 1:1 mapping of xml into the graph you can use <code>apoc.xml.import</code>.</p>
</div>
<div class="sect4">
<h5 id="_usage"><a class="link" href="#_usage">usage</a></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.import.xml(&lt;url&gt;, &lt;config&gt;?) YIELD node</code></pre>
</div>
</div>
<div class="paragraph">
<p>The procedure will return a node representing the xml document containing nodes/rels underneath mapping to the xml structure. The following mapping rules are applied:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">xml</th>
<th class="tableblock halign-left valign-top">label</th>
<th class="tableblock halign-left valign-top">properties</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">document</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">XmlDocument</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">_xmlVersion, _xmlEncoding</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">processing instruction</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">XmlProcessingInstruction</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">_piData, _piTarget</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Element/Tag</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">XmlTag</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">_name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Attribute</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">n/a</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">property in the XmlTag node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Text</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">XmlWord</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">for each word a separate node is created</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The nodes for the xml document are connected:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">relationship type</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">:IS_CHILD_OF</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">pointing to a nested xml element</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">:FIRST_CHILD_OF</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">pointing to the first child</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">:NEXT_SIBLING</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">pointing to the next xml element on the same nesting level</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">:NEXT</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">produces a linear chain through the full document</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">:NEXT_WORD</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">only produced if config map has <code>createNextWordRelationships:true</code>. Connects words in xml to a text flow.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect4">
<h5 id="_example_3"><a class="link" href="#_example_3">example</a></h5>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call
apoc.xml.import("https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.3/src/test/resources/books.xml",{createNextWordRelationships:
true})
yield node
return node;</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_graph_refactorings"><a class="link" href="#_graph_refactorings">Graph Refactorings</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_graph_refactoring_procedures"><a class="link" href="#_graph_refactoring_procedures">Graph Refactoring Procedures</a></h3>
<div class="paragraph">
<p>These procedures help refactor the structure of your graph.
This is helpful when you need to change your data model or for cleaning up data that was imported from an external source.</p>
</div>
<div class="sect3">
<h4 id="_merging_nodes"><a class="link" href="#_merging_nodes">Merging Nodes</a></h4>
<div class="paragraph">
<p>You can merge a list of nodes onto the first one in the list.</p>
</div>
<div class="paragraph">
<p>All relationships are merged onto that node too.
You can specify the merge behavior for properties globally and/or individually.</p>
</div>
<hr>
<div class="paragraph">
<p>MATCH (p:Person)
WITH p ORDER BY p.created DESC // newest one first
WITH p.email, collect(p) as nodes
CALL apoc.refactor.mergeNodes(nodes, {properties: {name:'discard', age:'override', kids:'combine', <code>addr.<strong></code>, 'override',<code>.</strong></code>: 'discard'}}) YIELD node
RETURN node
---</p>
</div>
<div class="paragraph">
<p>This config option also works for <code>apoc.refactor.mergeRelationships([rels],{config})</code>.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">type</th>
<th class="tableblock halign-left valign-top">operations</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">discard</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">the first nodes' property will remain if already set, otherwise the first property in list will be written</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">override</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"> last property in list wins</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">combine</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">if there is only one property in list, it will be set / kept as single property otherwise create an array, tries to coerce values</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_normalize_boolean_properties"><a class="link" href="#_normalize_boolean_properties">Normalize boolean properties</a></h4>
<div class="paragraph">
<p>Given raw data boolean properties are often represented by placeholder values.
This procedure turns them into boolean properties.</p>
</div>
<div class="paragraph">
<p>Will be true if "Y", YES"; false if "N", "NO"; null otherwise:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (n)
CALL apoc.refactor.normalizeAsBoolean(n, "prop", ["Y", "YES"], ["N", NO"])
RETURN n.prop</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_categorization"><a class="link" href="#_categorization">Categorization</a></h4>
<div class="paragraph">
<p>Categorize replaces string property values on nodes with relationship to a unique category node for that property value.</p>
</div>
<div class="paragraph">
<p>This example will turn all n.color properties into :HAS_ATTRIBUTE relationships to :Color nodes with a matching .colour property.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.refactor.categorize('color','HAS_ATTRIBUTE',true,'Color','colour',['popularity'],1)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Additionally, it will also copy over the first 'popularity' property value encountered on any node n for each newly created :Color node and remove any occurrences of that property value on nodes with the same 'Color'.</p>
</div>
<div class="sect4">
<h5 id="_graph_refactoring_examples"><a class="link" href="#_graph_refactoring_examples">Graph Refactoring Examples</a></h5>
<div class="paragraph">
<div class="title">Clone nodes</div>
<p>We create a dataset</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (f:Foo{name:'Foo'}),(b:Bar{name:'Bar'})</code></pre>
</div>
</div>
<div class="paragraph">
<p>As result we have two nodes</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.cloneNodes.dataset.png" alt="apoc.refactor.cloneNodes.dataset" width="800">
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (f:Foo{name:'Foo'}),(b:Bar{name:'Bar'}) WITH f,b
CALL apoc.refactor.cloneNodes([f,b]) yield input, output RETURN *</code></pre>
</div>
</div>
<div class="paragraph">
<p>As result we have the two nodes that we have created before and their clones</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.cloneNodes.png" alt="apoc.refactor.cloneNodes" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">Clone nodes with relationship</div>
<p>We create a dataset of two different nodes of type <code>Actor</code> connected with other two different node of type <code>Movie</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (k:Actor {name:'Keanu Reeves'})-[:ACTED_IN {role:'Neo'}]-&gt;(m:Movie {title:'The Matrix'}),
	   (t:Actor {name:'Tom Hanks'})-[:ACTED_IN {role:'Forrest'}]-&gt;(f:Movie {title:'Forrest Gump'}) RETURN *</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.cloneNodesWithRelationships.dataset.png" alt="apoc.refactor.cloneNodesWithRelationships.dataset" width="800">
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (k:Actor {name:'Keanu Reeves'}), (t:Actor {name:'Tom Hanks'})
CALL apoc.refactor.cloneNodesWithRelationships([k,t]) YIELD input, output RETURN *</code></pre>
</div>
</div>
<div class="paragraph">
<p>As result we have a copy of the nodes and relationships</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.cloneNodesWithRelationships.png" alt="apoc.refactor.cloneNodesWithRelationships" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">Merge nodes</div>
<p>We create two nodes with different properties</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (f:Person {name:'Foo'}), (b:Person {surname:'Bar'}) RETURN f,b</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.mergeNodes.dataset.png" alt="apoc.refactor.mergeNodes.dataset" width="800">
</div>
</div>
<div class="paragraph">
<p>Now we want to merge these nodes into one</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (f:Person {name:'Foo'}), (b:Person {surname:'Bar'})
CALL apoc.refactor.mergeNodes([f,b])
YIELD node RETURN node</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.mergeNodes.png" alt="apoc.refactor.mergeNodes" width="800">
</div>
</div>
<div class="paragraph">
<p>Thus we have one node with both properties <code>name</code> and <code>surname</code></p>
</div>
<div class="paragraph">
<div class="title">Redirect relationship to</div>
<p>We start with two nodes related each other with a relationship. We create a new node which we will use to redirect the relationship like end node</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (f:Foo)-[rel:FOOBAR {a:1}]-&gt;(b:Bar)
CREATE (p:Person {name:'Antony'})
RETURN *</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.to.dataset.png" alt="apoc.refactor.to.dataset" width="800">
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (f:Foo)-[rel:FOOBAR {a:1}]-&gt;(b:Bar) with id(rel) as id
MATCH (p:Person {name:'Antony'}) with p as p
MATCH ()-[r]-&gt;(), (p:Person)  CALL apoc.refactor.to(r, p) YIELD input, output RETURN *</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.to.png" alt="apoc.refactor.to" width="800">
</div>
</div>
<div class="paragraph">
<p>Now the relationship is towards the new node <code>Person</code></p>
</div>
<div class="paragraph">
<div class="title">Redirect relationship from</div>
<p>We start with two nodes related each other with a relationship. We create a new node which we will use to redirect the relationship like start node</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (f:Foo)-[rel:FOOBAR {a:1}]-&gt;(b:Bar)
CREATE (p:Person {name:'Antony'})
RETURN *</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.from.dataset.png" alt="apoc.refactor.from.dataset" width="800">
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (f:Foo)-[rel:FOOBAR {a:1}]-&gt;(b:Bar) with id(rel) as id
MATCH (p:Person {name:'Antony'}) with p as p
MATCH ()-[r]-&gt;(), (p:Person)  CALL apoc.refactor.from(r, p) YIELD input, output RETURN *</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.from.png" alt="apoc.refactor.from" width="800">
</div>
</div>
<div class="paragraph">
<p>Now the relationship starts from the new node <code>Person</code> from the old node <code>Bar</code></p>
</div>
<div class="paragraph">
<div class="title">Invert relationship</div>
<p>We start with two nodes connected by a relationship</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (f:Foo)-[rel:FOOBAR {a:1}]-&gt;(b:Bar)</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.invert.dataset.png" alt="apoc.refactor.invert.dataset" width="800">
</div>
</div>
<div class="paragraph">
<p>Now we want to invert the relationship direction</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (f:Foo)-[rel:FOOBAR {a:1}]-&gt;(b:Bar) WITH id(rel) as id
MATCH ()-[r]-&gt;() WHERE id(r) = id
CALL apoc.refactor.invert(r) yield input, output RETURN *</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.invert.call.png" alt="apoc.refactor.invert.call" width="800">
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.invert.png" alt="apoc.refactor.invert" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">Set type</div>
<p>With a simple relationship between two node</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (f:Foo)-[rel:FOOBAR]-&gt;(b:Bar)</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.setType.dataset.png" alt="apoc.refactor.setType.dataset" width="800">
</div>
</div>
<div class="paragraph">
<p>We can change the relationship type from <code>FOOBAR</code> to <code>NEW-TYPE</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (f:Foo)-[rel:FOOBAR]-&gt;(b:Bar) with rel
CALL apoc.refactor.setType(rel, 'NEW-TYPE') YIELD input, output RETURN *</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.setType.png" alt="apoc.refactor.setType" width="800">
</div>
</div>
<div class="listingblock">
<div class="title">Extract node from relationships</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (f:Foo)-[rel:FOOBAR {a:1}]-&gt;(b:Bar)</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.extractNode.dataset.png" alt="apoc.refactor.extractNode.dataset" width="800">
</div>
</div>
<div class="paragraph">
<p>We pass the ID of the relationship as parameter to extract a node</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (f:Foo)-[rel:FOOBAR {a:1}]-&gt;(b:Bar) WITH id(rel) as id
CALL apoc.refactor.extractNode(id,['FooBar'],'FOO','BAR')
YIELD input, output RETURN *</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.extractNode.png" alt="apoc.refactor.extractNode" width="800">
</div>
</div>
<div class="listingblock">
<div class="title">Collapse node to relationship</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (f:Foo)-[:FOO {a:1}]-&gt;(b:Bar {c:3})-[:BAR {b:2}]-&gt;(f) WITH id(b) as id
CALL apoc.refactor.collapseNode(id,'FOOBAR')
YIELD input, output RETURN *</code></pre>
</div>
</div>
<div class="paragraph">
<p>Before we have this situation</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.collapseNode.dataset.png" alt="apoc.refactor.collapseNode.dataset" width="800">
</div>
</div>
<div class="paragraph">
<p>And the result are</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.collapseNode.png" alt="apoc.refactor.collapseNode" width="800">
</div>
</div>
<div class="paragraph">
<p>The property of the two relationship and the property of the node are joined in one relationship that has the  properties <code>a:1</code>, <code>b:2</code>, <code>name:Bar</code></p>
</div>
<div class="listingblock">
<div class="title">Normalize As Boolean</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (:Person {prop: 'Y', name:'A'}),(:Person {prop: 'Yes', name:'B'}),(:Person {prop: 'NO', name:'C'}),(:Person {prop: 'X', name:'D'})</code></pre>
</div>
</div>
<div class="paragraph">
<p>As a resul we have four nodes with different properties <code>prop</code> like <code>Y</code>, <code>Yes</code>, <code>NO</code>, <code>X</code></p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.normalizeAsBoolean.dataset.png" alt="apoc.refactor.normalizeAsBoolean.dataset" width="800">
</div>
</div>
<div class="paragraph">
<p>Now we want to transform some properties into a boolean, <code>Y</code>, <code>Yes</code> into true and the properties <code>NO</code> into false.
The other properties that don&#8217;t match these possibilities will be set as <code>null</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (n)  CALL apoc.refactor.normalizeAsBoolean(n,'prop',['Y','Yes'],['NO']) WITH n ORDER BY n.id RETURN n.prop AS prop</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.normalizeAsBoolean.png" alt="apoc.refactor.normalizeAsBoolean" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">Categorize</div>
<p>First of all we create some nodes as dataset</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (:Person {prop: 'A', k: 'a', id: 1}),
       (:Person {prop: 'A', k: 'a', id: 2}),
       (:Person {prop: 'C', k: 'c', id: 3}),
       (:Person {                   id: 4}),
       (:Person {prop: 'B', k: 'b', id: 5}),
       (:Person {prop: 'C', k: 'c', id: 6})</code></pre>
</div>
</div>
<div class="paragraph">
<p>As result we have six nodes with label 'Person' with different properties</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.categorize.dataset.png" alt="apoc.refactor.categorize.dataset" width="800">
</div>
</div>
<div class="paragraph">
<p>Now we want to transform the property <code>prop</code> into a separate node with label <code>Letter</code> and transfer the properties of the nodes <code>Person</code>: <code>prop</code> (now renamed in <code>name</code>) and <code>k</code>.
The nodes <code>Person</code> will keep only the propertie <code>id</code>, and will be connected with a relationship <code>IS_A</code> with the new nodes <code>Letter</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.refactor.categorize('prop','IS_A',true,'Letter','name',['k'],1)</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.categorize.png" alt="apoc.refactor.categorize" width="800">
</div>
</div>
<div class="paragraph">
<p>The direction of the relationship (in this case outgoing) is defined by the third field, if <code>true</code> outgoing else incoming.
If a node doesn&#8217;t has the property <code>prop</code> (like node with <code>id: 4</code>) it won&#8217;t be managed.</p>
</div>
<div class="paragraph">
<div class="title">Merge relationships (combine properties)</div>
<p>We create two nodes with three relationships (two with same properties)</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (d:Person {name:'John'})
CREATE (p:Country {name:'USA'})
CREATE (d)-[:TRAVELS_TO {year:1995, reason:'work'}]-&gt;(p)
CREATE (d)-[:GOES_TO {year:["2010","2015"], reason:"fun"}]-&gt;(p)
CREATE (d)-[:FLIGHTS_TO {company:"Air America"}]-&gt;(p)
RETURN d,p</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.mergeRelationships.dataset.png" alt="apoc.refactor.mergeRelationships.dataset" width="800">
</div>
</div>
<div class="paragraph">
<p>Now we want to merge relationships into one combining properties</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (d:Person {name:'John'})
MATCH (p:Country {name:'USA'})
MATCH (d)-[r:TRAVELS_TO]-&gt;(p)
MATCH (d)-[h:GOES_TO]-&gt;(p)
MATCH (d)-[l:FLIGHTS_TO]-&gt;(p)
CALL apoc.refactor.mergeRelationships([r,h,l],{properties:"combine"}) YIELD rel
RETURN p,d</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.mergeRelationships.combine.png" alt="apoc.refactor.mergeRelationships.combine" width="800">
</div>
</div>
<div class="paragraph">
<p>Thus we have two nodes with one relationship with both properties <code>year</code>, <code>reason</code> and <code>company</code>.</p>
</div>
<div class="paragraph">
<div class="title">Merge relationships (discard properties)</div>
<p>We create two nodes with two relationships with same properties</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (d:Person {name:'John'})
CREATE (p:Country {name:'USA'})
CREATE (d)-[:TRAVELS_TO {year:1995, reason:'work'}]-&gt;(p)
CREATE (d)-[:GOES_TO {year:["2010","2015"], reason:"fun"}]-&gt;(p)
RETURN d,p</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.mergeRelationships.dataset2.png" alt="apoc.refactor.mergeRelationships.dataset2" width="800">
</div>
</div>
<div class="paragraph">
<p>Now we want to merge relationships into one discarding properties</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (d:Person {name:'John'})
MATCH (p:Country {name:'USA'})
MATCH (d)-[r:TRAVELS_TO]-&gt;(p)
MATCH (d)-[h:GOES_TO]-&gt;(p)
CALL apoc.refactor.mergeRelationships([r,h],{properties:"discard"}) YIELD rel
RETURN p,d</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.mergeRelationships.discard.png" alt="apoc.refactor.mergeRelationships.discard" width="800">
</div>
</div>
<div class="paragraph">
<p>Thus we have two nodes with one relationship with both properties. Properties values are the first read.</p>
</div>
<div class="paragraph">
<div class="title">Merge relationships (overwrite properties)</div>
<p>We create two nodes with two relationships with same properties</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (d:Person {name:'John'})
CREATE (p:Country {name:'USA'})
CREATE (d)-[:TRAVELS_TO {year:1995, reason:'work'}]-&gt;(p)
CREATE (d)-[:GOES_TO {year:["2010","2015"], reason:"fun"}]-&gt;(p)
RETURN d,p</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.mergeRelationships.dataset2.png" alt="apoc.refactor.mergeRelationships.dataset2" width="800">
</div>
</div>
<div class="paragraph">
<p>Now we want to merge relationships into one discarding properties</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (d:Person {name:'John'})
MATCH (p:Country {name:'USA'})
MATCH (d)-[r:TRAVELS_TO]-&gt;(p)
MATCH (d)-[h:GOES_TO]-&gt;(p)
CALL apoc.refactor.mergeRelationships([r,h],{properties:"overwrite"}) YIELD rel
RETURN p,d</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.refactor.mergeRelationships.overwrite.png" alt="apoc.refactor.mergeRelationships.overwrite" width="800">
</div>
</div>
<div class="paragraph">
<p>Thus we have two nodes with one relationship with both properties. Properties values are the last read.</p>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_using_cypher_and_apoc_to_move_a_property_value_to_a_label"><a class="link" href="#_using_cypher_and_apoc_to_move_a_property_value_to_a_label">Using Cypher and APOC to move a property value to a label</a></h3>
<div class="paragraph">
<p>You can use the procedure <a href="#_creating_data"><code>apoc.create.addLabels</code></a> to move a property to a label with Cypher as follows</p>
</div>
<div class="listingblock">
<div class="title">Create a node with property studio</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (:Movie {title: 'A Few Good Men', genre: 'Drama'})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Move the 'genre' property to a label and remove it as a property</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (n:Movie)
CALL apoc.create.addLabels( id(n), [ n.genre ] ) YIELD node
REMOVE node.genre
RETURN node</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_cypher_operations"><a class="link" href="#_cypher_operations">Cypher Operations</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_running_cypher_fragments"><a class="link" href="#_running_cypher_fragments">Running Cypher fragments</a></h3>
<div class="paragraph">
<p>We can use Cypher as safe, graph-aware, partially compiled scripting language within APOC.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 14.2857%;">
<col style="width: 14.2857%;">
<col style="width: 71.4286%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">type</th>
<th class="tableblock halign-left valign-top">qualified name</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.run</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.run(fragment, params) yield value - executes reading fragment with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.runFile</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runFile(file or url) - runs each statement in the file, all semicolon separated - currently no schema operations</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.runFiles</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runFiles([files or urls]) - runs each statement in the files, all semicolon separated</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.runSchemaFile</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runSchemaFile(file or url) - allows only schema operations, runs each schema statement in the file, all semicolon separated</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.runSchemaFiles</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runSchemaFiles([files or urls]) - allows only schema operations, runs each schema statement in the files, all semicolon separated</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.runMany</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runMany('cypher;\nstatements;',{params}) - runs each semicolon separated statement and returns summary - currently no schema operations</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.parallel</code></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.mapParallel</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.mapParallel(fragment, params, list-to-parallelize) yield value - executes fragment in parallel batches with the list segments being assigned to _</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.mapParallel2</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.mapParallel2(fragment, params, list-to-parallelize) yield value - executes fragment in parallel batches with the list segments being assigned to _</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.parallel2</code></p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.doIt</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.doIt(fragment, params) yield value - executes writing fragment with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.runTimeboxed</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runTimeboxed('cypherStatement',{params}, timeout) - abort statement after timeout ms if not finished</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.when</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.when(condition, ifQuery, elseQuery:'', params:{}) yield value - based on the conditional, executes read-only ifQuery or elseQuery with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.do.when</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.do.when(condition, ifQuery, elseQuery:'', params:{}) yield value - based on the conditional, executes writing ifQuery or elseQuery with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.case</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.case([condition, query, condition, query, &#8230;&#8203;], elseQuery:'', params:{}) yield value - given a list of conditional / read-only query pairs, executes the query associated with the first conditional evaluating to true (or the else query if none are true) with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.do.case</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.do.case([condition, query, condition, query, &#8230;&#8203;], elseQuery:'', params:{}) yield value - given a list of conditional / writing query pairs, executes the query associated with the first conditional evaluating to true (or the else query if none are true) with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">function</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.runFirstColumn</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.cypher.runFirstColumn(statement, params, expectMultipleValues) - executes statement with given parameters, returns first column only, if expectMultipleValues is true will collect results into an array</p></td>
</tr>
</tbody>
</table>
<div class="sect3">
<h4 id="_example_fast_node_counts_by_label"><a class="link" href="#_example_fast_node_counts_by_label">Example: Fast Node-Counts by Label</a></h4>
<div class="paragraph">
<p>Counts by label are quickly provided by the counts-store, but only if they are the the single thing in the query, like</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (:Person) RETURN count(*);</code></pre>
</div>
</div>
<div class="paragraph">
<p>It also works to combine several with <code>UNION ALL</code>, but not via <code>WITH</code></p>
</div>
<div class="listingblock">
<div class="title">Doesn&#8217;t work</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (:Person) WITH count(*) as people
MATCH (:Movie) RETURN people, count(*) as movies;</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Works</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (:Person) RETURN count(*)
UNION ALL
MATCH (:Movie) RETURN count(*);</code></pre>
</div>
</div>
<div class="paragraph">
<p>But with <code>apoc.cypher.run</code> we can construct the statement and run each of them individually, so it completes in a few ms.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call db.labels() yield label
call apoc.cypher.run("match (:`"+label+"`) return count(*) as count", null) yield value
return label, value.count as count</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can use a similar approach to get the property-keys per label:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL db.labels() yield label
call apoc.cypher.run("MATCH (n:`"+label+"`) RETURN keys(n) as keys LIMIT 1",null) yield value
RETURN label, value.keys as keys</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_running_a_cypher_statement_timeboxed"><a class="link" href="#_running_a_cypher_statement_timeboxed">Running a cypher statement timeboxed</a></h4>
<div class="paragraph">
<p>There&#8217;s a way to terminate a cypher statement if it takes longer than a given threshold. Consider an expensive statement calculating cross product of shortestpaths for each pair of nodes:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.cypher.runTimeboxed("match (n),(m) match p=shortestPath((n)-[*]-(m)) return p", null, 10000) yield value
return value.p</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_run_multiple_statements"><a class="link" href="#_run_multiple_statements">Run multiple Statements</a></h4>
<div class="paragraph">
<p>This procedure runs each semicolon separated statement and returns summary - currently no schema operations.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>apoc.cypher.runMany('cypher;\nstatements;',{params},[{statistics:true,timeout:10}])</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_run_cypher_script_files"><a class="link" href="#_run_cypher_script_files">Run Cypher Script Files</a></h4>
<div class="paragraph">
<p>Runs each statement in the file / each file, all semicolon separated</p>
</div>
<div class="paragraph">
<p>You can use them with files that are usually run by cypher-shell or neo4j-shell, e.g. generated by <code>apoc.export.cypher.*</code>
They automatically skip <code>:begin/:commit/:rollback</code> operations as they are executed in a single transaction per file.</p>
</div>
<div class="paragraph">
<p>Data Operations only:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>apoc.cypher.runFile(file or url,[{config}])</code></p>
</li>
<li>
<p><code>apoc.cypher.runFiles([files or urls],[{config})])</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Schema Operations only:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>apoc.cypher.runSchemaFile(file or url,[{config}])</code></p>
</li>
<li>
<p><code>apoc.cypher.runSchemaFiles([files or urls],[{config})])</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>apoc.cypher.run*File(s)</code> procedures have some optional configuration:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>{statistics:true/false}</code> to output a row of update-stats per statement, default is true</p>
</li>
<li>
<p><code>{timeout:1 or 10}</code> for how long the stream waits for new data, default is 10</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_conditional_cypher_execution"><a class="link" href="#_conditional_cypher_execution">Conditional cypher execution</a></h4>
<div class="paragraph">
<p>Sometimes queries require conditional execution logic that can&#8217;t be adequately expressed in Cypher, even with CASE.</p>
</div>
<div class="paragraph">
<p>APOC&#8217;s conditional execution procedures simulate an if / else structure, where a supplied boolean condition determines which cypher query is executed.</p>
</div>
<div class="sect5">
<h6 id="_when_procedures"><a class="link" href="#_when_procedures">WHEN Procedures</a></h6>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.when(condition, ifQuery, elseQuery:'', params:{}) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">based on the condition, executes read-only ifQuery or elseQuery with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.do.when(condition, ifQuery, elseQuery:'', params:{}) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">based on the condition, executes writing ifQuery or elseQuery with the given parameters</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>For example, if we wanted to match to neighbor nodes one and two traversals away from a start node, and return the smaller set (either those one hop away, or those that are two hops away), we might use:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher"> MATCH (start:Node)-[:REL]-&gt;(a)-[:REL]-&gt;(b)
 WITH collect(distinct a) as aNodes, collect(distinct b) as bNodes
 CALL apoc.when(size(aNodes) &lt;= size(bNodes), 'RETURN aNodes as resultNodes', 'RETURN bNodes as resultNodes', {aNodes:aNodes, bNodes:bNodes}) YIELD value
 RETURN value.resultNodes as resultNodes</code></pre>
</div>
</div>
<div class="paragraph">
<p>Or, if we wanted to conditionally set or create graph elements if we deem some account to be suspicious, but still want to continue other query operations in either case, we could use <code>apoc.do.when</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (acc:Account)
OPTIONAL MATCH (acc)-[r:ACCESSED_BY]-&gt;(suspect:User)
WHERE suspect.id in {suspiciousUsersIdList}
CALL apoc.do.when(r IS NOT NULL, 'SET acc:Suspicious', '', {acc:acc}) YIELD value
// ignore value and continue
WITH acc
...</code></pre>
</div>
</div>
</div>
<div class="sect5">
<h6 id="_case_procedures"><a class="link" href="#_case_procedures">CASE Procedures</a></h6>
<div class="paragraph">
<p>For more complex conditional logic, case procedures allow for a variable-length list of condition / query pairs, where the query following the first conditional evaluating to true is executed. An elseQuery block is executed if none of the conditionals are true.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.case([condition, query, condition, query, &#8230;&#8203;], elseQuery:'', params:{}) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">given a list of conditional / read-only query pairs, executes the query associated with the first conditional evaluating to true (or the else query if none are true) with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.do.case([condition, query, condition, query, &#8230;&#8203;], elseQuery:'', params:{}) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">given a list of conditional / writing query pairs, executes the query associated with the first conditional evaluating to true (or the else query if none are true) with the given parameters</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>If we wanted to MATCH to selection nodes in a column, we could use entirely different MATCHES depending on query parameters, or based on data already in the graph:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher"> MATCH (me:User{id:{myId}})
 CALL apoc.case(
  [{selection} = 'friends', "RETURN [(me)-[:FRIENDS]-(friend) | friend] as selection",
   {selection} = 'coworkers', "RETURN [(me)-[:WORKS_AT*2]-(coworker) | coworker] as selection",
   {selection} = 'all', "RETURN apoc.coll.union([(me)-[:FRIENDS]-(friend) | friend], [(me)-[:WORKS_AT*2]-(coworker) | coworker]) as selection"],
   'RETURN [] as selection', {me:me}) YIELD value
 RETURN value.selection as selection</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_job_management_and_periodic_execution"><a class="link" href="#_job_management_and_periodic_execution">Job management and periodic execution</a></h3>
<div class="sect3">
<h4 id="_introduction_asynchronous_transactional_execution"><a class="link" href="#_introduction_asynchronous_transactional_execution">Introduction asynchronous transactional execution</a></h4>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
this document is work in progress
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Cypher is great for querying graphs and importing and updating graph structures.
While during imports you can use <code>PERIODIC COMMIT</code> to control transaction sizes in memory,
for other graph refactorings it&#8217;s not that easy to commit transactions regularly to free memory for new update state.</p>
</div>
<div class="paragraph">
<p>Also sometimes you want to schedule execution of Cypher statements to run regularly in the background or asynchronously ("fire &amp; forget").</p>
</div>
<div class="paragraph">
<p>The <code>apoc.periodic.*</code> procedures provide such capabilities.</p>
</div>
<div class="paragraph">
<p>Many procedures run in the background or asynchronously. This setting overrides the default thread pool size (processors*2).</p>
</div>
<div class="paragraph">
<p><code>apoc.jobs.default.num_threads=10</code></p>
</div>
<div class="paragraph">
<p>Many periodic procedures rely on a scheduled executor that has a pool of threads with a default fixed size (processors/4, at least 1). You can configure the pool size using the following configuration property:</p>
</div>
<div class="paragraph">
<p><code>apoc.jobs.scheduled.num_threads=10</code></p>
</div>
</div>
<div class="sect3">
<h4 id="_apoc_periodic_iterate"><a class="link" href="#_apoc_periodic_iterate">apoc.periodic.iterate</a></h4>
<div class="paragraph">
<p>With <code>apoc.periodic.iterate</code> you provide 2 statements, the <strong>first</strong> outer statement is providing a stream of values to be processed.
The <strong>second</strong>, inner statement processes <strong>one</strong> element at a time or with <code>iterateList:true</code> the whole batch at a time.</p>
</div>
<div class="paragraph">
<p>The results of the outer statement are passed into the inner statement as parameters, they are automatically made available with their names.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 3. configuration options</caption>
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">param</th>
<th class="tableblock halign-left valign-top">default</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">batchSize</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1000</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">that many inner statements are run within a single tx params: {_count, _batch}</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">parallel</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">run inner statement in parallel, note that statements might deadlock</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">retries</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">if the inner statement fails with an error, sleep 100ms and retry until retries-count is reached, param {_retry}</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">iterateList</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">the inner statement is only executed once but the whole batchSize list is passed in as parameter {_batch}</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">params</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">{}</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">externally passed in map of params</p></td>
</tr>
</tbody>
</table>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
We plan to make <code>iterateList:true</code> the default in upcoming releases, due to the automatic UNWINDing and providing of nested results as variables,
most queries should continue work.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>So if you were to add an <code>:Actor</code> label to several million <code>:Person</code> nodes, you would run:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.periodic.iterate(
"MATCH (p:Person) WHERE (p)-[:ACTED_IN]-&gt;() RETURN p",
"SET p:Actor", {batchSize:10000, parallel:true})</code></pre>
</div>
</div>
<div class="paragraph">
<p>Which would take 10k people from the stream and update them in a single transaction, executing the <strong>second</strong> statement for each person.</p>
</div>
<div class="paragraph">
<p>Those executions can happen in parallel as updating node-labels or properties doesn&#8217;t conflict.</p>
</div>
<div class="paragraph">
<p>If you do more complex operations like updating or removing relationships, either <strong>don&#8217;t use parallel</strong> OR make sure that you batch the work in a way that each subgraph of data is updated in one operation, e.g. by transferring the root objects.
If you attempt complex operations, try to use e.g. <code>retries:3</code> to retry failed operations.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.periodic.iterate(
"MATCH (o:Order) WHERE o.date &gt; '2016-10-13' RETURN o",
"MATCH (o)-[:HAS_ITEM]-&gt;(i) WITH o, sum(i.value) as value SET o.value = value", {batchSize:100, parallel:true})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">iterating over the whole batch (more efficient)</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.periodic.iterate(
"MATCH (o:Order) WHERE o.date &gt; '2016-10-13' RETURN o",
"MATCH (o)-[:HAS_ITEM]-&gt;(i) WITH o, sum(i.value) as value SET o.value = value", {batchSize:100, iterateList:true, parallel:true})</code></pre>
</div>
</div>
<div class="paragraph">
<p>The stream of other data can also come from another source, like a different database, CSV or JSON file.</p>
</div>
</div>
<div class="sect3">
<h4 id="_apoc_periodic_commit"><a class="link" href="#_apoc_periodic_commit">apoc.periodic.commit</a></h4>
<div class="paragraph">
<p>Especially for graph processing it is useful to run a query repeatedly in separate transactions until it doesn&#8217;t process and generates any results anymore.
So you can iterate in batches over elements that don&#8217;t fulfill a condition and update them so that they do afterwards.</p>
</div>
<div class="paragraph">
<p>The query is executed repatedly in separate transactions until it returns 0.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.periodic.commit("
match (user:User) WHERE exists( user.city )
with user limit {limit}
MERGE (city:City {name:user.city})
MERGE (user)-[:LIVES_IN]-&gt;(city)
REMOVE user.city
RETURN count(*)
",{limit:10000})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>+=======+==========+
|updates|executions|
+=======+==========+
|2000000|200       |
+-------+----------+</pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_apoc_periodic_countdown"><a class="link" href="#_apoc_periodic_countdown">apoc.periodic.countdown</a></h4>
<div class="paragraph">
<p>Repeats a statement until the termination is reached. The statement must return a numeric value and it should decrement (like a monotonically decreasing function). When the return value reaches 0 than the iteration stops.
For example, define a counter with a numeric property:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (counter:Counter) SET counter.c = 10</code></pre>
</div>
</div>
<div class="paragraph">
<p>and decrement this property by 1 each second:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.periodic.countdown('decrement',"MATCH (counter:Counter) SET counter.c = counter.c - 1 RETURN counter.c as count", 1)</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_further_functions"><a class="link" href="#_further_functions">Further Functions</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 14.2857%;">
<col style="width: 14.2857%;">
<col style="width: 71.4286%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">type</th>
<th class="tableblock halign-left valign-top">qualified name</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.periodic.list</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.list - list all jobs</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.periodic.commit</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.commit(statement,params) - runs the given statement in separate transactions until it returns 0</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.periodic.cancel</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.cancel(name) - cancel job with the given name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.periodic.submit</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.submit('name',statement) - submit a one-off background statement</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.periodic.repeat</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.repeat('name',statement,repeat-rate-in-seconds) submit a repeatedly-called background statement</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.periodic.countdown</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.countdown('name',statement,repeat-rate-in-seconds) submit a repeatedly-called background statement until it returns 0</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.periodic.rock_n_roll_while</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.rock_n_roll_while('some cypher for knowing when to stop', 'some cypher for iteration', 'some cypher as action on each iteration', 10000) YIELD batches, total - run the action statement in batches over the iterator statement&#8217;s results in a separate thread. Returns number of batches and total processed rows</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.periodic.iterate</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.iterate('statement returning items', 'statement per item', {batchSize:1000,iterateList:false,parallel:true}) YIELD batches, total - run the second statement for each item returned by the first statement. Returns number of batches and total processed rows</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">procedure</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.periodic.rock_n_roll</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.periodic.rock_n_roll('some cypher for iteration', 'some cypher as action on each iteration', 10000) YIELD batches, total - run the action statement in batches over the iterator statement&#8217;s results in a separate thread. Returns number of batches and total processed rows</p></td>
</tr>
</tbody>
</table>
<div class="ulist">
<ul>
<li>
<p>there are also static methods <code>Jobs.submit</code>, and <code>Jobs.schedule</code> to be used from other procedures</p>
</li>
<li>
<p>jobs list is checked / cleared every 10s for finished jobs</p>
</li>
</ul>
</div>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function() {
    $('#table-all').DataTable();
} );
</script>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_virtual"><a class="link" href="#_virtual">Virtual</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_virtual_nodes_rels"><a class="link" href="#_virtual_nodes_rels">Virtual Nodes/Rels</a></h3>
<div class="paragraph">
<p>Virtual Nodes and Relationships don&#8217;t exist in the graph, they are only returned to the UI/user for representing a graph projection.
They can be visualized or processed otherwise.
Please note that they have negative id&#8217;s.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.vNode(['Label'], {key:value,&#8230;&#8203;}) YIELD node</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.create.vNode(['Label'], {key:value,&#8230;&#8203;})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.vNodes(['Label'], [{key:value,&#8230;&#8203;}])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns virtual nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.vRelationship(nodeFrom,'KNOWS',{key:value,&#8230;&#8203;}, nodeTo) YIELD rel</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.create.vRelationship(nodeFrom,'KNOWS',{key:value,&#8230;&#8203;}, nodeTo)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.vPattern({_labels:['LabelA'],key:value},'KNOWS',{key:value,&#8230;&#8203;}, {_labels:['LabelB'],key:value})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual pattern</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.vPatternFull(['LabelA'],{key:value},'KNOWS',{key:value,&#8230;&#8203;},['LabelB'],{key:value})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual pattern</p></td>
</tr>
</tbody>
</table>
<div class="sect3">
<h4 id="_virtual_nodes_rels_example"><a class="link" href="#_virtual_nodes_rels_example">Virtual Nodes/Rels Example</a></h4>
<div class="paragraph">
<div class="title">Virtual node and virtual relationship <code>vNode</code>, <code>vRelationship</code></div>
<p>From a simple dataset</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE(a:Person)-[r:ACTED_IN]-&gt;(b:Movie)</code></pre>
</div>
</div>
<div class="paragraph">
<p>We can create a virtual copy, adding as attribute <code>name</code> the labels value</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (a)-[r]-&gt;(b)
WITH head(labels(a)) AS l, head(labels(b)) AS l2, type(r) AS rel_type, count(*) as count
CALL apoc.create.vNode([l],{name:l}) yield node as a
CALL apoc.create.vNode([l2],{name:l2}) yield node as b
CALL apoc.create.vRelationship(a,rel_type,{count:count},b) yield rel
RETURN *;</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.create.vRelationshipAndvNode.png" alt="apoc.create.vRelationshipAndvNode" width="800">
</div>
</div>
<div class="paragraph">
<p>Virtual nodes and virtual relationships have always a negative id</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/vNodeId.png" alt="vNodeId" width="200">
</div>
</div>
<div class="listingblock">
<div class="title">Virtual pattern <code>vPattern</code></div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.create.vPattern({_labels:['Person'],name:'Mary'},'KNOWS',{since:2012},{_labels:['Person'],name:'Michael'})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.create.vPattern.png" alt="apoc.create.vPattern" width="800">
</div>
</div>
<div class="paragraph">
<p>We can add more labels, just adding them on <code>_labels</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.create.vPattern({_labels:['Person', 'Woman'],name:'Mary'},'KNOWS',{since:2012},{_labels:['Person', 'Man'],name:'Michael'})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.create.vPatternLabels.png" alt="apoc.create.vPatternLabels" width="800">
</div>
</div>
<div class="listingblock">
<div class="title">Virtual pattern full <code>vPatternFull</code></div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.create.vPatternFull(['British','Person'],{name:'James', age:28},'KNOWS',{since:2009},['Swedish','Person'],{name:'Daniel', age:30})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.create.vPatternFull.png" alt="apoc.create.vPatternFull" width="800">
</div>
</div>
<div class="paragraph">
<p>We can create a virtual pattern from an existing one</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE(a:Person {name:'Daniel'})-[r:KNOWS]-&gt;(b:Person {name:'John'})</code></pre>
</div>
</div>
<div class="paragraph">
<p>From this dataset we can create a virtual pattern</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (a)-[r]-&gt;(b)
WITH head(labels(a)) AS labelA, head(labels(b)) AS labelB, type(r) AS rel_type, a.name AS aName, b.name AS bName
CALL apoc.create.vPatternFull([labelA],{name: aName},rel_type,{since:2009},[labelB],{name: bName}) yield from, rel, to
RETURN *;</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.create.vPatternFullTwo.png" alt="apoc.create.vPatternFullTwo" width="800">
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_virtual_graph"><a class="link" href="#_virtual_graph">Virtual Graph</a></h3>
<div class="paragraph">
<p>Create a graph object (map) from information that&#8217;s passed in.
It&#8217;s basic structure is: <code>{name:"Name",properties:{properties},nodes:[nodes],relationships:[relationships]}</code></p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.from(data,'name',{properties}) yield graph</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing it tries its best to extract the graph information from the data you pass in</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.fromData([nodes],[relationships],'name',{properties})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.fromPaths(path,'name',{properties})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.fromPaths([paths],'name',{properties})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.fromDB('name',{properties})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.fromCypher('statement',{params},'name',{properties})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing</p></td>
</tr>
</tbody>
</table>
<div class="sect3">
<h4 id="_virtual_graph_examples"><a class="link" href="#_virtual_graph_examples">Virtual Graph Examples</a></h4>
<div class="paragraph">
<p>We create a dataset for our examples</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (a:Actor {name:'Tom Hanks'})-[r:ACTED_IN {roles:'Forrest'}]-&gt;(m:Movie {title:'Forrest Gump'}) RETURN *</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Virtual graph from data</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (n)-[r]-&gt;(m) CALL apoc.graph.fromData([n,m],[r],'test',{answer:42}) YIELD graph RETURN *</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Virtual graph from path</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH path = (n)-[r]-&gt;(m) CALL apoc.graph.fromPath(path,'test',{answer:42}) YIELD graph RETURN *</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Virtual graph from paths</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH path = (n)-[r]-&gt;(m) CALL apoc.graph.fromPaths([path],'test',{answer:42}) YIELD graph RETURN *</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Virtual graph from DB</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.graph.fromDB('test',{answer:42}) YIELD graph RETURN *</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Virtual graph from Cypher</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.graph.fromCypher('MATCH (n)-[r]-&gt;(m) RETURN *',null,'test',{answer:42}) YIELD graph RETURN *</code></pre>
</div>
</div>
<div class="paragraph">
<p>As a result we have a virtual graph object for later processing</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.graph.png" alt="apoc.graph" width="800">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_triggers"><a class="link" href="#_triggers">Triggers</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>In a trigger you register Cypher statements that are called when data in Neo4j is changed, you can run them before or after commit.</p>
</div>
<div class="paragraph">
<p>Enable <code>apoc.trigger.enabled=true</code> in <code>$NEO4J_HOME/config/neo4j.conf</code> first.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.trigger.add(name, statement, selector) yield name, statement, installed</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add a trigger statement under a name, in the statement you can use {createdNodes}, {deletedNodes} etc., the selector is {phase:'before/after/rollback'} returns previous and new trigger information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.trigger.remove(name) yield name, statement, installed</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">remove previously added trigger, returns trigger information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.trigger.list() yield name, statement, installed</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">update and list all installed triggers</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.trigger.pause(name)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">it pauses the trigger</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.trigger.resume(name)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">it resumes the paused trigger</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The transaction data from Neo4j is turned into appropriate data structures to be consumed as parameters to your statement.</p>
</div>
<div class="paragraph">
<p>The parameters available are:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Statement</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">transactionId</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns the id of the transaction</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">commitTime</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the date of the transaction in milliseconds</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">createdNodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">when a node is created our trigger fires (list of nodes)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">createdRelationships</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">when a relationship is created our trigger fires (list of relationships)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">deletedNodes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">when a node is delated our trigger fires (list of nodes)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">deletedRelationships</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">when a relationship is delated our trigger fires (list of relationships)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">removedLabels</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">when a label is removed our trigger fires (map of label to list of nodes)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">removedNodeProperties</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">when a properties of node is removed our trigger fires (map of key to list of map of key,old,node)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">removedRelationshipProperties</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">when a properties of relationship is removed our trigger fires (map of key to list of map of key,old,relationship)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">assignedLabels</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">when a labes is assigned our trigger fires  (map of label to list of nodes)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">assignedNodeProperties</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">when node property is assigned our trigger fires (map of key to list of map of key,old,new,node)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">assignedRelationshipProperties</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">when relationship property is assigned our trigger fires (map of key to list of map of key,old,new,relationship)</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>You can use these helper functions to extract nodes by label or</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 4. Helper Functions</caption>
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.trigger.nodesByLabel({assignedLabels/assignedNodeProperties},'Label')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">function to filter labelEntries by label, to be used within a trigger statement with {assignedLabels} and {removedLabels} {phase:'before/after/rollback'} returns previous and new trigger information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.trigger.propertiesByKey({assignedNodeProperties},'key')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">function to filter propertyEntries by property-key, to be used within a trigger statement with {assignedNode/RelationshipProperties} and {removedNode/RelationshipProperties}. Returns [{old,[new],key,node,relationship}]</p></td>
</tr>
</tbody>
</table>
<div class="sect4">
<h5 id="_triggers_examples"><a class="link" href="#_triggers_examples">Triggers Examples</a></h5>
<div class="paragraph">
<div class="title">Set properties connected to a node</div>
<p>We could add a trigger that when is added a specific property on a node, that property is added to all the nodes connected to this node</p>
</div>
<div class="paragraph">
<p>Dataset</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (d:Person {name:'Daniel'})
CREATE (l:Person {name:'Mary'})
CREATE (t:Person {name:'Tom'})
CREATE (j:Person {name:'John'})
CREATE (m:Person {name:'Michael'})
CREATE (a:Person {name:'Anne'})
CREATE (l)-[:DAUGHTER_OF]-&gt;(d)
CREATE (t)-[:SON_OF]-&gt;(d)
CREATE (t)-[:BROTHER]-&gt;(j)
CREATE (a)-[:WIFE_OF]-&gt;(d)
CREATE (d)-[:SON_OF]-&gt;(m)
CREATE (j)-[:SON_OF]-&gt;(d)</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.trigger.add.setAllConnectedNodes.dataset.png" alt="apoc.trigger.add.setAllConnectedNodes.dataset" width="800">
</div>
</div>
<div class="paragraph">
<p>Now we add the trigger using <code>apoc.trigger.propertiesByKey</code> on the <code>surname</code> property</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.trigger.add('setAllConnectedNodes','UNWIND apoc.trigger.propertiesByKey({assignedNodeProperties},"surname") as prop
WITH prop.node as n
MATCH(n)-[]-(a)
SET a.surname = n.surname', {phase:'after'});</code></pre>
</div>
</div>
<div class="paragraph">
<p>So when we add the <code>surname</code> property on a node, it&#8217;s added to all the nodes connected (in this case one level deep)</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (d:Person {name:'Daniel'})
SET d.surname = 'William'</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.trigger.add.setAllConnectedNodes.png" alt="apoc.trigger.add.setAllConnectedNodes" width="800">
</div>
</div>
<div class="paragraph">
<p>The <code>surname</code> property is add/change on all related nodes</p>
</div>
<div class="paragraph">
<div class="title">Update labels</div>
<p>Dataset</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (k:Actor {name:'Keanu Reeves'})
CREATE (l:Actor {name:'Laurence Fishburne'})
CREATE (c:Actor {name:'Carrie-Anne Moss'})
CREATE (m:Movie {title:'Matrix'})
CREATE (k)-[:ACT_IN]-&gt;(m)
CREATE (l)-[:ACT_IN]-&gt;(m)
CREATE (c)-[:ACT_IN]-&gt;(m)</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.trigger.add.setLabels.png" alt="apoc.trigger.add.setLabels" width="800">
</div>
</div>
<div class="paragraph">
<p>We add a trigger using <code>apoc.trigger.nodesByLabel</code> that when the label <code>Actor</code> of a node is removed, update all labels <code>Actor</code> with <code>Person</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.trigger.add('updateLabels',"UNWIND apoc.trigger.nodesByLabel({removedLabels},'Actor') AS node
MATCH (n:Actor)
REMOVE n:Actor SET n:Person SET node:Person", {phase:'before'})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH(k:Actor {name:'Keanu Reeves'})
REMOVE k:Actor</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.trigger.add.setLabelsResult.png" alt="apoc.trigger.add.setLabelsResult" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">Create relationship on a new node</div>
<p>We can add a trigger that connect every new node with label <code>Actor</code> and as  <code>name</code> property a specific value</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.trigger.add('create-rel-new-node',"UNWIND {createdNodes} AS n
MATCH (m:Movie {title:'Matrix'})
WHERE n:Actor AND n.name IN ['Keanu Reeves','Laurence Fishburne','Carrie-Anne Moss']
CREATE (n)-[:ACT_IN]-&gt;(m)", {phase:'before'})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (k:Actor {name:'Keanu Reeves'})
CREATE (l:Actor {name:'Laurence Fishburne'})
CREATE (c:Actor {name:'Carrie-Anne Moss'})
CREATE (a:Actor {name:'Tom Hanks'})
CREATE (m:Movie {title:'Matrix'})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.trigger.add.create-rel-new-node.png" alt="apoc.trigger.add.create rel new node" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">Pause trigger</div>
<p>We have the possibility to pause a trigger without remove it, if we will need it in the future</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.trigger.pause.png" alt="apoc.trigger.pause" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">Resume paused trigger</div>
<p>When you need again of a trigger paused</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.trigger.resume.png" alt="apoc.trigger.resume" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">Enforcing property type</div>
<p>For this example, we would like that all the <code>reference</code> node properties are of type <code>STRING</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.trigger.add("forceStringType",
"UNWIND apoc.trigger.propertiesByKey({assignedNodeProperties}, 'reference') AS prop
CALL apoc.util.validate(apoc.meta.type(prop) &lt;&gt; 'STRING', 'expected string property type, got %s', [apoc.meta.type(prop)]) RETURN null", {phase:'before'})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (a:Node) SET a.reference = 1

Neo.ClientError.Transaction.TransactionHookFailed</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Other examples</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.trigger.add('timestamp','UNWIND {createdNodes} AS n SET n.ts = timestamp()');
CALL apoc.trigger.add('lowercase','UNWIND {createdNodes} AS n SET n.id = toLower(n.name)');
CALL apoc.trigger.add('txInfo',   'UNWIND {createdNodes} AS n SET n.txId = {transactionId}, n.txTime = {commitTime}', {phase:'after'});
CALL apoc.trigger.add('count-removed-rels','MATCH (c:Counter) SET c.count = c.count + size([r IN {deletedRelationships} WHERE type(r) = "X"])')
CALL apoc.trigger.add('lowercase-by-label','UNWIND apoc.trigger.nodesByLabel({assignedLabels},'Person') AS n SET n.id = toLower(n.name)')</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_schema"><a class="link" href="#_schema">Schema</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>To retrieve indexes and constraints information for all the node labels in your database, you can use the following procedure:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.schema.nodes() yield name, label, properties, status, type</code></pre>
</div>
</div>
<div class="paragraph">
<p>Where the outputs are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>name of the index/constraint,</p>
</li>
<li>
<p>label</p>
</li>
<li>
<p>properties, (for Neo4j 3.1 and lower versions is a single element array) that are affected by the constraint</p>
</li>
<li>
<p>status, for index can be one of the following values: ONLINE, POPULATING and FAILED</p>
</li>
<li>
<p>type, always "INDEX" for indexes, constraint type for constraints</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>To retrieve the constraint information for all the relationship types in your database, you can use the following procedure:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.schema.relationships() yield name, type, properties, status</code></pre>
</div>
</div>
<div class="paragraph">
<p>Where the outputs are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>name of the constraint</p>
</li>
<li>
<p>type of the relationship</p>
</li>
<li>
<p>properties, (for Neo4j 3.1 and lower versions is a single element array) that are affected by the constraint</p>
</li>
<li>
<p>status</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>N.B. Constraints for property existence on nodes and relationships are available only for the Enterprise Edition.</p>
</div>
<div class="sect4">
<h5 id="_examples_4"><a class="link" href="#_examples_4">Examples</a></h5>
<div class="sect6">
<h7 id="_list_indexes_and_constraints_for_nodes"><a class="link" href="#_list_indexes_and_constraints_for_nodes">List indexes and constraints for nodes</a></h7>
<div class="paragraph">
<p>Given the following cypher statements:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE CONSTRAINT ON (bar:Bar) ASSERT exists(bar.foobar)
CREATE CONSTRAINT ON (bar:Bar) ASSERT bar.foo IS UNIQUE
CREATE INDEX ON :Person(name)
CREATE INDEX ON :Publication(name)
CREATE INDEX ON :Source(name)</code></pre>
</div>
</div>
<div class="paragraph">
<p>When you</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.schema.nodes()</code></pre>
</div>
</div>
<div class="paragraph">
<p>you will receive this result:</p>
</div>
<div class="imageblock">
<div class="content">
<img src="img/apoc.schema.nodes.png" alt="apoc.schema.nodes">
</div>
</div>
</div>
<div class="sect6">
<h7 id="_list_constraints_for_relationships"><a class="link" href="#_list_constraints_for_relationships">List constraints for relationships</a></h7>
<div class="paragraph">
<p>Given the following cypher statements:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE CONSTRAINT ON ()-[like:LIKED]-() ASSERT exists(like.day)
CREATE CONSTRAINT ON ()-[starred:STARRED]-() ASSERT exists(starred.month)</code></pre>
</div>
</div>
<div class="paragraph">
<p>When you</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.schema.relationships()</code></pre>
</div>
</div>
<div class="paragraph">
<p>you will receive this result:</p>
</div>
<div class="imageblock">
<div class="content">
<img src="img/apoc.schema.relationships.png" alt="apoc.schema.relationships">
</div>
</div>
</div>
<div class="sect5">
<h6 id="_check_if_an_index_or_a_constraint_exists_for_a_label_and_property"><a class="link" href="#_check_if_an_index_or_a_constraint_exists_for_a_label_and_property">Check if an index or a constraint exists for a Label and property</a></h6>
<div class="paragraph">
<p>Given the previous index definitions, running this statement:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">RETURN apoc.schema.node.indexExists("Publication", ["name"])</code></pre>
</div>
</div>
<div class="paragraph">
<p>produces the following output:</p>
</div>
<div class="imageblock">
<div class="content">
<img src="img/apoc.schema.node.indexExists.png" alt="apoc.schema.node.indexExists">
</div>
</div>
<div class="paragraph">
<p>Given the previous constraint definitions, running this statement:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">RETURN apoc.schema.node.constraintExists("Bar", ["foobar"])</code></pre>
</div>
</div>
<div class="paragraph">
<p>produces the following output:</p>
</div>
<div class="imageblock">
<div class="content">
<img src="img/apoc.schema.node.constraintExists.png" alt="apoc.schema.node.constraintExists">
</div>
</div>
<div class="paragraph">
<p>If you want to check if a constraint exists for a relationship you can run this statement:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">RETURN apoc.schema.relationship.constraintExists('LIKED', ['day'])</code></pre>
</div>
</div>
<div class="paragraph">
<p>and you get the following result:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="img/apoc.schema.relationship.constraintExists.png" alt="apoc.schema.relationship.constraintExists"></span></p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_atomic"><a class="link" href="#_atomic">Atomic</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Atomic procedures handle the concurrency, it&#8217;s add a lock to the resource.
If two users access to the same resource at the same time, with the parameter <code>times</code> (default value 5) we can determine how many time retry to modify the resource, until the lock is release.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.atomic.add(node/relationship, "property", number, [times]) YIELD oldValue, newValue</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">adds the number to the value of the property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.atomic.subtract(node/relationship, "property", number, [times]) YIELD oldValue, newValue</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtracts the number to the value of the property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.atomic.concat(node/relationship, "property", "string", [times]) YIELD oldValue, newValue</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">concatenate the string to the property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.atomic.insert(node/relationship, "property", position, object, [times]) YIELD oldValue, newValue</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">inserts the object in the chosen position of the array</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.atomic.remove(node/relationship, "property", position, [times]) YIELD oldValue, newValue</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">remove from the array the element to the position selected</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.atomic.update(node/relationship, "property", "expression", [times]) YIELD oldValue, newValue</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">update the property with the result of the expression</p></td>
</tr>
</tbody>
</table>
<div class="sect2">
<h3 id="_atomic_examples"><a class="link" href="#_atomic_examples">Atomic Examples</a></h3>
<div class="paragraph">
<div class="title">add</div>
<p>Dataset</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (p:Person {name:'Tom',age: 40})</code></pre>
</div>
</div>
<div class="paragraph">
<p>We can add 10 to the property <code>age</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (n:Person {name:'Tom'})
CALL apoc.atomic.add(n,'age',10,5) YIELD oldValue, newValue
RETURN n</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.atomic.add.png" alt="apoc.atomic.add" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">subtract</div>
<p>From the previous example we can go back to <code>age</code>: 40</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (n:Person {name:'Tom'})
CALL apoc.atomic.subtract(n,'age',10,5) YIELD oldValue, newValue
RETURN n</code></pre>
</div>
</div>
<div class="paragraph">
<div class="title">concat</div>
<p>Dataset</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (p:Person {name:'Will',age: 35})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (p:Person {name:'Will',age: 35})
CALL apoc.atomic.concat(p,"name",'iam',5) YIELD newValue
RETURN p</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.atomic.concat.png" alt="apoc.atomic.concat" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">insert</div>
<p>Dataset</p>
</div>
<div class="paragraph">
<p>we add a propery <code>children</code> that is an array</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (p:Person {name:'Tom', children: ['Anne','Sam','Paul']})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.atomic.insert.png" alt="apoc.atomic.insert" width="800">
</div>
</div>
<div class="paragraph">
<p>Now we add <code>Mary</code> to propery children at the position 2</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (p:Person {name:'Tom'})
CALL apoc.atomic.insert(p,'children',2,'Mary',5) YIELD newValue
RETURN p</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.atomic.insert.result.png" alt="apoc.atomic.insert.result" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">remove</div>
<p>Dataset</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CREATE (p:Person {name:'Tom', cars: ['Class A','X3','Focus']})</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now we remove the element <code>X3</code> which is at the position 1 from the array <code>cars</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (p:Person {name:'Tom'})
CALL apoc.atomic.remove(p,'cars',1,5) YIELD newValue
RETURN p</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.atomic.remove.png" alt="apoc.atomic.remove" width="800">
</div>
</div>
<div class="paragraph">
<div class="title">update</div>
<p>Dataset</p>
</div>
<div class="listingblock">
<div class="content">
<pre>CREATE (p:Person {name:'Tom', salary1:1800, salary2:1500})</pre>
</div>
</div>
<div class="paragraph">
<p>We want to update <code>salary1</code> with the result of an expression.
The expression always have to be referenced with the <code>n.</code> that refers to the node/rel passed as parameter.
If we rename our node/rel (as in the example above) we have anyway to refer to it in the expression as <code>n</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (p:Person {name:'Tom'})
CALL apoc.atomic.update(p,'salary1','n.salary1*3 + n.salary2',5) YIELD newValue
RETURN p</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.atomic.update.png" alt="apoc.atomic.update" width="800">
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_bolt"><a class="link" href="#_bolt">Bolt</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Bolt procedures allows to accessing other databases via bolt protocol.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 60%;">
<col style="width: 40%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.bolt.execute(urlOrKey, statement, params, config) YIELD row</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">access to other databases via bolt for read and write</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.bolt.load(urlOrKey, statement, params, config) YIELD row</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">access to other databases via bolt for read</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p><strong>urlOrKey</strong> param allows users to decide if send url by apoc or if put it into neo4j.conf file.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>apoc</strong> : write the complete url in his right position on the apoc.</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.bolt.load("bolt://user:password@localhost:7687","match(p:Person {name:{name}}) return p", {name:'Michael'})</code></pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>neo4j.conf</strong> : here the are two choices:</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>1) <strong>complete url</strong>: write the complete url with the param apoc.bolt.url;</p>
</div>
<div class="listingblock">
<div class="title">apoc</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.bolt.load("","match(p:Person {name:{name}}) return p", {name:'Michael'})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">neo4jConf</div>
<div class="content">
<pre class="highlight"><code class="language-txt" data-lang="txt">//simple url
apoc.bolt.url=bolt://user:password@localhost:7687</code></pre>
</div>
</div>
<div class="paragraph">
<p>2) <strong>by key</strong>: set the url with a personal key apoc.bolt.yourKey.url; in this case in the apoc on the url param user has to insert the key.</p>
</div>
<div class="listingblock">
<div class="title">apoc</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.bolt.load("test","match(p:Person {name:{name}}) return p", {name:'Michael'})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">neo4jConf</div>
<div class="content">
<pre class="highlight"><code class="language-txt" data-lang="txt">//with key
apoc.bolt.test.url=bolt://user:password@localhost:7687
apoc.bolt.production.url=bolt://password:test@localhost:7688</code></pre>
</div>
</div>
<div class="paragraph">
<p>Config available are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>statistics</code>: possible values are true/false, the default value is false. This config print the execution statistics;</p>
</li>
<li>
<p><code>virtual</code>: possible values are true/false, the default value is false. This config return result in virtual format and not in map format, in apoc.bolt.load.</p>
</li>
</ul>
</div>
<div class="sect2">
<h3 id="_driver_configuration"><a class="link" href="#_driver_configuration">Driver configuration</a></h3>
<div class="paragraph">
<p>To set the configuration of the Driver, you can add the parameter <code>driverConfig</code> in the config.
Is&#8217;s a map of values, the values that we don&#8217;t pass to the config, are set to the default value.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">{logging='INFO', encryption=true, logLeakedSessions:true, maxIdleConnectionPoolSize:10, idleTimeBeforeConnectionTest:-1, trustStrategy:'TRUST_ALL_CERTIFICATES',
 routingFailureLimit: 1, routingRetryDelayMillis:5000, connectionTimeoutMillis:5000, maxRetryTimeMs:30000 }</code></pre>
</div>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">param</th>
<th class="tableblock halign-left valign-top">description</th>
<th class="tableblock halign-left valign-top">possible values/ types</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">logging</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">logging provider to use</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">INFO, WARNING, OFF, SEVERE, CONFIG, FINE, FINER</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">encryption</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Disable or enabled encryption</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true, false</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">logLeakedSessions</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Disable or enable logging of leaked sessions</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true, false</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">maxIdleConnectionPoolSize</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Max number of connections</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">number</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">idleTimeBeforeConnectionTest</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Pooled connections that have been idle in the pool for longer than this timeout</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Milliseconds</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">trustStrategy</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify how to determine the authenticity of an encryption certificate provided by the Neo4j instance we are connecting to</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">TRUST_ALL_CERTIFICATES, TRUST_SYSTEM_CA_SIGNED_CERTIFICATES, or directly a custom certificate</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">routingFailureLimit</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">the number of times to retry each server in the list of routing servers</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">number</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">routingRetryDelayMillis</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify how long to wait before retrying to connect to a routing server</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Milliseconds</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">connectionTimeoutMillis</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify socket connection timeout</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Milliseconds</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">maxRetryTimeMs</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify the maximum time transactions are allowed to retry</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Milliseconds</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>You can find all the values in the documentation <a href="http://neo4j.com/docs/api/java-driver/current/org/neo4j/driver/v1/Config.ConfigBuilder.html">Config.ConfigBuilder</a></p>
</div>
</div>
<div class="sect2">
<h3 id="_bolt_examples"><a class="link" href="#_bolt_examples">Bolt Examples</a></h3>
<div class="paragraph">
<p><strong>Return node in map format</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.bolt.execute("bolt://user:password@localhost:7687",
"match(p:Person {name:{name}}) return p", {name:'Michael'})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.bolt.execute.nodemap.png" alt="apoc.bolt.execute.nodemap" width="800">
</div>
</div>
<div class="paragraph">
<p><strong>Return node in virtual Node format</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.bolt.load("bolt://user:password@localhost:7687",
"match(p:Person {name:{name}}) return p", {name:'Michael'}, {virtual:true})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.bolt.load.virtualnode.png" alt="apoc.bolt.load.virtualnode" width="800">
</div>
</div>
<div class="paragraph">
<p><strong>Create node and return statistic</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.bolt.execute("bolt://user:password@localhost:7687",
"create(n:Node {name:{name}})", {name:'Node1'}, {statistics:true})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.bolt.execute.createandstatistics.png" alt="apoc.bolt.execute.createandstatistics" width="800">
</div>
</div>
<div class="paragraph">
<p><strong>Return more scalar values</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.bolt.execute("bolt://user:password@localhost:7687",
"match (n:Person {name:{name}}) return n.age as age, n.name as name, n.surname as surname", {name:'Michael'})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.bolt.execute.scalarmulti.png" alt="apoc.bolt.execute.scalarmulti" width="800">
</div>
</div>
<div class="paragraph">
<p><strong>Return relationship in a map format</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.bolt.load("bolt://user:password@localhost:7687",
"MATCH (n:Person{name:{name}})-[r:KNOWS]-&gt;(p) return r as rel", {name:'Anne'})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.bolt.load.relmap.png" alt="apoc.bolt.load.relmap" width="800">
</div>
</div>
<div class="paragraph">
<p><strong>Return virtual path</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.bolt.load("bolt://user:password@localhost:7687",
"START n=node({idNode}) MATCH path= (n)-[r:REL_TYPE*..3]-&gt;(o) return path", {idNode:200}, {virtual:true})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.bolt.load.returnvirtualpath.png" alt="apoc.bolt.load.returnvirtualpath" width="800">
</div>
</div>
<div class="paragraph">
<p><strong>Create a Node with params in input</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.bolt.execute("bolt://user:password@localhost:7687",
"CREATE (n:Car{brand:{brand},model:{model},year:{year}}) return n", {brand:'Ferrari',model:'California',year:2016})</code></pre>
</div>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.bolt.execute.createwithparams.png" alt="apoc.bolt.execute.createwithparams" width="800">
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_appendix_complete_overview"><a class="link" href="#_appendix_complete_overview">Appendix: Complete Overview</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_configuration_options"><a class="link" href="#_configuration_options">Configuration Options</a></h3>
<div class="paragraph">
<p>Set these config options in <code>$NEO4J_HOME/neo4j.conf</code></p>
</div>
<div class="paragraph">
<p>All boolean options default to <strong>false</strong>, i.e. they are disabled, unless mentioned otherwise.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.trigger.enabled=false/true</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Enable triggers</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.ttl.enabled=false/true</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Enable time to live background task</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.ttl.schedule=5</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Set frequency in seconds to run ttl background task (default 60)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.import.file.use_neo4j_config=true</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Enable reading properties: <code>dbms.directories.import</code>,<code>dbms.security.allow_csv_import_from_file_urls</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.import.file.enabled=true</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Enable reading local files from disk</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.file.enabled=true</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Enable writing local files to disk</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.jdbc.&lt;key&gt;.uri=jdbc-url-with-credentials</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">store jdbc-urls under a key to be used by apoc.load.jdbc</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.&lt;key&gt;.uri=es-url-with-credentials</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">store es-urls under a key to be used by elasticsearch procedures</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.mongodb.&lt;key&gt;.uri=mongodb-url-with-credentials</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">store mongodb-urls under a key to be used by mongodb procedures</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.couchbase.&lt;key&gt;.uri=couchbase-url-with-credentials</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">store couchbase-urls under a key to be used by couchbase procedures</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.jobs.scheduled.num_threads=number-of-threads</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Many periodic procedures rely on a scheduled executor that has a pool of threads with a default fixed size. You can configure the pool size using this configuration property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.jobs.default.num_threads=number-of-threads</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Number of threads in the default APOC thread pool used for background executions.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_manual_indexes_2"><a class="link" href="#_manual_indexes_2">Manual Indexes</a></h3>
<div class="sect3">
<h4 id="_index_queries_2"><a class="link" href="#_index_queries_2">Index Queries</a></h4>
<div class="paragraph">
<p>Procedures to add to and query manual indexes</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
Please note that there are (case-sensitive) <a href="http://neo4j.com/docs/developer-manual/current/#cypher-schema">automatic schema indexes</a>, for equality, non-equality, existence, range queries, starts with, ends-with and contains!
</td>
</tr>
</table>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addAllNodes('index-name',{label1:['prop1',&#8230;&#8203;],&#8230;&#8203;}, {options})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add all nodes to this full text index with the given fields, additionally populates a 'search' index field with all of them in one place</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addNode(node,['prop1',&#8230;&#8203;])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add node to an index for each label it has</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addNodeByLabel('Label',node,['prop1',&#8230;&#8203;])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add node to an index for the given label</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addNodeByName('name',node,['prop1',&#8230;&#8203;])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add node to an index for the given name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addNodeMap(node,{key:value})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"> add node to an index for each label it has with the given attributes which can also be computed</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addNodeMapByName(index, node,{key:value})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add node to an index for each label it has with the given attributes which can also be computed</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addRelationship(rel,['prop1',&#8230;&#8203;])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add relationship to an index for its type</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addRelationshipByName('name',rel,['prop1',&#8230;&#8203;])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add relationship to an index for the given name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addRelationshipMap(rel,{key:value})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add relationship to an index for its type indexing the given document which can be computed</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.addRelationshipMapByName(index, rel,{key:value})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add relationship to an index for its type indexing the given document which can be computed</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.removeNodeByName('name',node) remove node from an index for the given name</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.index.removeRelationshipByName('name',rel) remove relationship from an index for the given name</p></td>
</tr>
</tbody>
</table>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.index.nodes-with-score.jpg" alt="apoc.index.nodes with score" width="600">
</div>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.search('index-name', 'query') YIELD node, weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">search for the first 100 nodes in the given full text index matching the given lucene query returned by relevance</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.nodes('Label','prop:value*') YIELD node, weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">lucene query on node index with the given label name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.relationships('TYPE','prop:value*') YIELD rel, weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">lucene query on relationship index with the given type name</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.between(node1,'TYPE',node2,'prop:value*') YIELD rel, weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">lucene query on relationship index with the given type name bound by either or both sides (each node parameter can be null)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.out(node,'TYPE','prop:value*') YIELD node, weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">lucene query on relationship index with the given type name for <strong>outgoing</strong> relationship of the given node, <strong>returns end-nodes</strong></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.in(node,'TYPE','prop:value*') YIELD node, weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">lucene query on relationship index with the given type name for <strong>incoming</strong> relationship of the given node, <strong>returns start-nodes</strong></p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_index_management_2"><a class="link" href="#_index_management_2">Index Management</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.index.list() YIELD type,name,config</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">lists all manual indexes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.index.remove('name') YIELD type,name,config</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">removes manual indexes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.index.forNodes('name',{config}) YIELD type,name,config</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">gets or creates manual node index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.index.forRelationships('name',{config}) YIELD type,name,config</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">gets or creates manual relationship index</p></td>
</tr>
</tbody>
</table>
<div class="listingblock">
<div class="title">Add node to index example</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">match (p:Person) call apoc.index.addNode(p,["name","age"]) RETURN count(*);
// 129s for 1M People
call apoc.index.nodes('Person','name:name100*') YIELD node, weight return * limit 2</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_schema_index_queries"><a class="link" href="#_schema_index_queries">Schema Index Queries</a></h4>
<div class="paragraph">
<p>Schema Index lookups that keep order and can apply limits</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.orderedRange(label,key,min,max,sort-relevance,limit) yield node</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">schema range scan which keeps index order and adds limit, values can be null, boundaries are inclusive</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.index.orderedByText(label,key,operator,value,sort-relevance,limit) yield node</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">schema string search which keeps index order and adds limit, operator is 'STARTS WITH' or 'CONTAINS'</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.schema.properties.distinct(label,key) yield values</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">quickly returns all distinct values in a label for a given key</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.schema.properties.distinctCount(label,key) yield label,key,value,count</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">quickly returns all distinct values and counts in a label for a given key; empty label means any label and empty key means any key</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_meta_graph"><a class="link" href="#_meta_graph">Meta Graph</a></h3>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc.meta.graph.jpg" alt="apoc.meta.graph" width="600">
</div>
</div>
<div class="paragraph">
<p>Returns a virtual graph that represents the labels and relationship-types available in your database and how they are connected.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 5. Procedures</caption>
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.meta.graphSample()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">examines the database statistics to build the meta graph, very fast, might report extra relationships</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.meta.graph</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">examines the database statistics to create the meta-graph, post filters extra relationships by sampling</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.meta.subGraph({labels:[labels],rels:[rel-types],excludes:[label,rel-type,&#8230;&#8203;]})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">examines a sample sub graph to create the meta-graph</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.meta.data</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">examines a subset of the graph to provide a tabular meta information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.meta.schema</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">examines a subset of the graph to provide a map-like meta information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.meta.stats  yield labelCount, relTypeCount, propertyKeyCount, nodeCount, relCount, labels, relTypes, stats</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns the information stored in the transactional database statistics</p></td>
</tr>
</tbody>
</table>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 6. Functions</caption>
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.meta.type(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">type name of a value (<code>INTEGER,FLOAT,STRING,BOOLEAN,RELATIONSHIP,NODE,PATH,NULL,UNKNOWN,MAP,LIST</code>)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.meta.isType(value,type)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a row if type name matches none if not</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.meta.types(node or relationship or map)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a a map of property-keys to their names</p></td>
</tr>
</tbody>
</table>
<div class="listingblock">
<div class="title">isType example</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (n:Person)
RETURN apoc.meta.isType(n.age,"INTEGER") as ageType</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_schema_2"><a class="link" href="#_schema_2">Schema</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.schema.assert({indexLabel:[indexKeys],&#8230;&#8203;},{constraintLabel:[constraintKeys],&#8230;&#8203;}, dropExisting : true) yield label, key, unique, action</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">drops all other existing indexes and constraints when <code>dropExisting</code> is <code>true</code> (default is <code>true</code>), and asserts that at the end of the operation the given indexes and unique constraints are there, each label:key pair is considered one constraint/label.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_locking"><a class="link" href="#_locking">Locking</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.lock.nodes([nodes])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">acquires a write lock on the given nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.lock.rels([relationships])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">acquires a write lock on the given relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.lock.all([nodes],[relationships])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">acquires a write lock on the given nodes and relationships</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_from_tojson"><a class="link" href="#_from_tojson">from/toJson</a></h3>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 7. Functions</caption>
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toJson([1,2,3])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">converts value to json string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toJson( {a:42,b:"foo",c:[1,2,3]})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">converts value to json map</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toSortedJsonMap(node|map, ignoreCase:true )</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a JSON map with keys sorted alphabetically, with optional case sensitivity</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.fromJsonList('[1,2,3]')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">converts json list to Cypher list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.fromJsonMap( '{"a":42,"b":"foo","c":[1,2,3]}')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">converts json map to Cypher map</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toTree([paths],[lowerCaseRels=true])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a stream of nested documents representing the at least one root of these paths</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.getJsonProperty(node,key)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">converts serialized JSON in property back to original object</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.getJsonPropertyMap(node,key)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">converts serialized JSON in property back to map</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.convert.toTree([paths]) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a stream of nested documents representing the at least one root of these paths</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.convert.setJsonProperty(node,key,complexValue)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sets value serialized to JSON as property with the given name on the node</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_export_import"><a class="link" href="#_export_import">Export / Import</a></h3>
<div class="sect3">
<h4 id="_export_to_csv"><a class="link" href="#_export_to_csv">Export to CSV</a></h4>
<div class="paragraph">
<p><code>YIELD file, source, format, nodes, relationships, properties, time, rows</code></p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.csv.query(query,file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports results from the Cypher statement as CSV to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.csv.all(file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports whole database as CSV to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.csv.data(nodes,rels,file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports given nodes and relationships as CSV to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.csv.graph(graph,file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports given graph object as CSV to the provided file</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_export_to_cypher_script"><a class="link" href="#_export_to_cypher_script">Export to Cypher Script</a></h4>
<div class="paragraph">
<p>Make sure to set the config options in your <code>neo4j.conf</code></p>
</div>
<div class="listingblock">
<div class="title">neo4j.conf</div>
<div class="content">
<pre>apoc.export.file.enabled=true
apoc.import.file.enabled=true</pre>
</div>
</div>
<div class="paragraph">
<p>Data is exported as Cypher statements to the given file.</p>
</div>
<div class="paragraph">
<p>It is possible to choose between three export formats:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>neo4j-shell</code>: for Neo4j Shell and partly <code>apoc.cypher.runFile</code></p>
</li>
<li>
<p><code>cypher-shell</code>: for Cypher shell</p>
</li>
<li>
<p><code>plain</code>: doesn&#8217;t output begin / commit / await just plain Cypher</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>To change the export format, you have to set it on the config params like <code>{format : "cypher-shell"}</code>.</p>
</div>
<div class="paragraph">
<p>By default the format is <code>neo4j-shell</code>.</p>
</div>
<div class="paragraph">
<p>If you want to export to separate files, e.g. to later use the <code>apoc.cypher.runFiles/runSchemaFiles</code> procedures, you can add <code>separateFiles:true</code>.</p>
</div>
<div class="paragraph">
<p>It is possible to choose between four cypher update operation types:
To change the cypher update operation, you have to set it on the config params like <code>{cypherFormat: "updateAll"}</code></p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>create</code>: all CREATE</p>
</li>
<li>
<p><code>updateAll</code>: MERGE instead of CREATE</p>
</li>
<li>
<p><code>addStructure</code>: MATCH for nodes + MERGE for rels</p>
</li>
<li>
<p><code>updateStructure</code>: MERGE + MATCH for nodes and rels</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Format and cypherFormat can be used both in the same query giving you complete control over the exact export format:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.export.cypher.query(
"MATCH (p1:Person)-[r:KNOWS]-&gt;(p2:Person) RETURN p1,r,p2",
"/tmp/friendships.cypher",
{format:'plain',cypherFormat:'updateStructure'})`</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>YIELD file, source, format, nodes, relationships, properties, time</code></p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.cypher.all(file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports whole database incl. indexes as Cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.cypher.data(nodes,rels,file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports given nodes and relationships incl. indexes as Cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.cypher.graph(graph,file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports given graph object incl. indexes as Cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.cypher.query(query,file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports nodes and relationships from the Cypher statement incl. indexes as Cypher statements to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.cypher.schema(file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports all schema indexes and constraints to cypher</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_roundtrip_example"><a class="link" href="#_roundtrip_example">Roundtrip Example</a></h4>
<div class="paragraph">
<p>You can use this roundtrip example e.g. on the <code>:play movies</code> movie graph.</p>
</div>
<div class="paragraph">
<p>Make sure to set the config options in your <code>neo4j.conf</code></p>
</div>
<div class="listingblock">
<div class="title">neo4j.conf</div>
<div class="content">
<pre>apoc.export.file.enabled=true
apoc.import.file.enabled=true</pre>
</div>
</div>
<div class="paragraph">
<p>Export the data in plain format and multiple files:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.export.cypher.query("match (n)-[r]-&gt;(n2) return * limit 100",
 "/tmp/mysubset.cypher",
 {format:'plain',separateFiles:true});</code></pre>
</div>
</div>
<div class="paragraph">
<p>This should result in 4 files in your directory.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-shell" data-lang="shell">ls -1 /tmp/mysubset.*
/tmp/mysubset.cleanup.cypher
/tmp/mysubset.nodes.cypher
/tmp/mysubset.relationships.cypher
/tmp/mysubset.schema.cypher</code></pre>
</div>
</div>
<div class="paragraph">
<p>Import the data in 4 steps, first the schema, then nodes and relationships, then cleanup.</p>
</div>
<hr>
<div class="paragraph">
<p>call apoc.cypher.runSchemaFile('/tmp/mysubset.schema.cypher');
call apoc.cypher.runFiles(['/tmp/mysubset.nodes.cypher','/tmp/mysubset.relationships.cypher']);</p>
</div>
<div class="paragraph">
<p>call apoc.cypher.runFile('/tmp/mysubset.cleanup.cypher');
call apoc.cypher.runSchemaFile('/tmp/mysubset.cleanup.cypher');
---</p>
</div>
<div class="paragraph">
<p>The <code>run*</code> procedures have some optional config:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>{statistics:true/false}</code> to output a row of update-stats per statement, default is true</p>
</li>
<li>
<p><code>{timeout:1 or 10}</code> for how long the stream waits for new data, default is 10</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_stream_back_exported_cypher_script_as_columns"><a class="link" href="#_stream_back_exported_cypher_script_as_columns">Stream back Exported Cypher Script as columns</a></h3>
<div class="paragraph">
<p>If you leave off the file-name as <code>null</code> the export will instead be streamed back.</p>
</div>
<div class="paragraph">
<p>In general there will be a <code>cypherStatements</code> column with the script.</p>
</div>
<div class="paragraph">
<p>If you use multi-file-splitting as configuration parameter, there will be extra columns with content for</p>
</div>
<div class="ulist">
<ul>
<li>
<p>nodeStatements</p>
</li>
<li>
<p>relationshipStatements</p>
</li>
<li>
<p>cleanupStatements</p>
</li>
<li>
<p>schemaStatements</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If you also specify the <code>streamStatements:true</code> then each batch (by <code>batchSize</code> which defaults to 10k) of statements will be returned as a row.
So you can use your client to reconstruct the cypher script.</p>
</div>
<div class="listingblock">
<div class="title">Simple Example for Streaming</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">echo "
CALL apoc.export.cypher.all(null,{streamStatements:true,batchSize:100}) YIELD cypherStatements RETURN cypherStatements;
" | ./bin/cypher-shell --non-interactive --format plain</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_examples_5"><a class="link" href="#_examples_5">Examples</a></h3>
<div class="listingblock">
<div class="title">exportAll (neo4j-shell format)</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.export.cypher.all({fileName},{config})</code></pre>
</div>
</div>
<div class="paragraph">
<p>Result:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">begin
CREATE (:`Foo`:`UNIQUE IMPORT LABEL` {`name`:"foo", `UNIQUE IMPORT ID`:0});
CREATE (:`Bar` {`name`:"bar", `age`:42});
CREATE (:`Bar`:`UNIQUE IMPORT LABEL` {`age`:12, `UNIQUE IMPORT ID`:2});
commit
begin
CREATE INDEX ON :`Foo`(`name`);
CREATE CONSTRAINT ON (node:`Bar`) ASSERT node.`name` IS UNIQUE;
CREATE CONSTRAINT ON (node:`UNIQUE IMPORT LABEL`) ASSERT node.`UNIQUE IMPORT ID` IS UNIQUE;
commit
schema await
begin
MATCH (n1:`UNIQUE IMPORT LABEL`{`UNIQUE IMPORT ID`:0}), (n2:`Bar`{`name`:"bar"}) CREATE (n1)-[:`KNOWS`]-&gt;(n2);
commit
begin
MATCH (n:`UNIQUE IMPORT LABEL`)  WITH n LIMIT 20000 REMOVE n:`UNIQUE IMPORT LABEL` REMOVE n.`UNIQUE IMPORT ID`;
commit
begin
DROP CONSTRAINT ON (node:`UNIQUE IMPORT LABEL`) ASSERT node.`UNIQUE IMPORT ID` IS UNIQUE;
commit</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">exportSchema (neo4j-shell format)</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.export.cypher.schema({fileName},{config})</code></pre>
</div>
</div>
<div class="paragraph">
<p>Result:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">begin
CREATE INDEX ON :`Foo`(`name`);
CREATE CONSTRAINT ON (node:`Bar`) ASSERT node.`name` IS UNIQUE;
commit
schema await</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_graphml_import_export"><a class="link" href="#_graphml_import_export">GraphML Import / Export</a></h4>
<div class="paragraph">
<p>GraphML is used by other tools, like Gephi and CytoScape to read graph data.</p>
</div>
<div class="paragraph">
<p><code>YIELD file, source, format, nodes, relationships, properties, time</code></p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.import.graphml(file-or-url,{batchSize: 10000, readLabels: true, storeNodeIds: false, defaultRelationshipType:"RELATED"})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">imports graphml into the graph</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.graphml.all(file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports whole database as graphml to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.graphml.data(nodes,rels,file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports given nodes and relationships as graphml to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.graphml.graph(graph,file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports given graph object as graphml to the provided file</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.export.graphml.query(query,file,config)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">exports nodes and relationships from the Cypher statement as graphml to the provided file</p></td>
</tr>
</tbody>
</table>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 8. configuration options</caption>
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">param</th>
<th class="tableblock halign-left valign-top">default</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">batchSize</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">20000</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">define the batch size</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">delim</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">","</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">define the delimiter character (export csv)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">quotes</p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">quote-character used for CSV</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">useTypes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add type on file header (export csv and graphml export)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">format</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">"neo4j-shell"</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In export to Cypher script define the export format. Possible values are: "cypher-shell","neo4j-shell" and "plain"</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">nodesOfRelationships</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">if enabled add relationship between nodes (export Cypher)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">storeNodeIds</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">set nodes' ids (import/export graphml)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">readLabels</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">read nodes' labels (import/export graphml)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">defaultRelationshipType</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">"RELATED"</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">set relationship type (import/export graphml)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">separateFiles</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">export results in separated file by type (nodes, relationships..)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">cypherFormat</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">create</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">In export to cypher script, define the cypher format (for example use <code>MERGE</code> instead of <code>CREATE</code>). Possible values are: "create", "updateAll", "addStructure", "updateStructure".</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_loading_data_from_rdbms"><a class="link" href="#_loading_data_from_rdbms">Loading Data from RDBMS</a></h3>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/apoc-jdbc-northwind-load.jpg" alt="apoc jdbc northwind load" width="600">
</div>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.load.jdbc('jdbc:derby:derbyDB','PERSON') YIELD row CREATE (:Person {name:row.name})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">load from relational database, either a full table or a sql statement</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.load.jdbc('jdbc:derby:derbyDB','SELECT * FROM PERSON WHERE AGE &gt; 18')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">load from relational database, either a full table or a sql statement</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.load.driver('org.apache.derby.jdbc.EmbeddedDriver')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">register JDBC driver of source database</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>To simplify the JDBC URL syntax and protect credentials, you can configure aliases in <code>conf/neo4j.conf</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>apoc.jdbc.myDB.url=jdbc:derby:derbyDB</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>CALL apoc.load.jdbc('jdbc:derby:derbyDB','PERSON')

becomes

CALL apoc.load.jdbc('myDB','PERSON')</pre>
</div>
</div>
<div class="paragraph">
<p>The 3rd value in the <code>apoc.jdbc.&lt;alias&gt;.url=</code> effectively defines an alias to be used in  <code>apoc.load.jdbc('&lt;alias&gt;',&#8230;&#8203;.</code></p>
</div>
</div>
<div class="sect2">
<h3 id="_loading_data_from_web_apis_json_xml_csv"><a class="link" href="#_loading_data_from_web_apis_json_xml_csv">Loading Data from Web-APIs (JSON, XML, CSV)</a></h3>
<div class="paragraph">
<p>Supported protocols are <code>file</code>, <code>http</code>, <code>https</code>, <code>s3</code> with redirect allowed. In case no protocol is passed, this procedure set will try to check whether the url is actually a file.
Moreover, if 'apoc.import.file.use_neo4j_config' is enabled the procedures verify whether file system access is allowed and eventually constrained to a specific directory by
reading the two configuration parameters <code>dbms.security.allow_csv_import_from_file_urls</code> and <code>dbms.directories.import</code> respectively.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.load.json('http://example.com/map.json', [path], [config]) YIELD value as person CREATE (p:Person) SET p = person</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">load from JSON URL (e.g. web-api) to import JSON as stream of values if the JSON was an array or a single value if it was a map</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.load.xml('http://example.com/test.xml', ['xPath'], [config]) YIELD value as doc CREATE (p:Person) SET p.name = doc.name</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">load from XML URL (e.g. web-api) to import XML as single nested map with attributes and <code>_type</code>, <code>_text</code> and <code>_children</code> fields.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.load.xmlSimple('http://example.com/test.xml') YIELD value as doc CREATE (p:Person) SET p.name = doc.name</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">load from XML URL (e.g. web-api) to import XML as single nested map with attributes and <code><em>type</code>, <code>_text</code> fields and <code></em>&lt;childtype&gt;</code> collections per child-element-type.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.load.csv('url',{sep:";"}) YIELD lineNo, list, strings, map, stringMap</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">load CSV fom URL as stream of values<br>
config contains any of: <code>{skip:1,limit:5,header:false,sep:'TAB',ignore:['aColumn'],arraySep:';',results:['map','list','strings','stringMap'],<br>
nullValues:[''],mapping:{years:{type:'int',arraySep:'-',array:false,name:'age',ignore:false,nullValues:['n.A.']}}</code></p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<div class="title">Using S3 protocol</div>
<p>For using S3 protocol you have to copy these jars into the plugins directory:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>aws-java-sdk-core-1.11.250.jar (<a href="https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-core/1.11.250" class="bare">https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-core/1.11.250</a>)</p>
</li>
<li>
<p>aws-java-sdk-s3-1.11.250.jar (<a href="https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3/1.11.250" class="bare">https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3/1.11.250</a>)</p>
</li>
<li>
<p>httpclient-4.4.8.jar (<a href="https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient/4.5.4" class="bare">https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient/4.5.4</a>)</p>
</li>
<li>
<p>httpcore-4.5.4.jar (<a href="https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore/4.4.8" class="bare">https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore/4.4.8</a>)</p>
</li>
<li>
<p>joda-time-2.9.9.jar (<a href="https://mvnrepository.com/artifact/joda-time/joda-time/2.9.9" class="bare">https://mvnrepository.com/artifact/joda-time/joda-time/2.9.9</a>)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>S3 Url must be:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>s3://accessKey:secretKey@endpoint:port/bucket/key
or</p>
</li>
<li>
<p>s3://endpoint:port/bucket/key?accessKey=accessKey&amp;secretKey=secretKey</p>
</li>
</ul>
</div>
<div class="paragraph">
<div class="title">failOnError</div>
<p>Adding on config the parameter <code>failOnError:false</code> (by default <code>true</code>), in case of error the procedure don&#8217;t fail but just return zero rows.</p>
</div>
</div>
<div class="sect2">
<h3 id="_interacting_with_elastic_search"><a class="link" href="#_interacting_with_elastic_search">Interacting with Elastic Search</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 60%;">
<col style="width: 40%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.stats(host-url-Key)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">elastic search statistics</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.get(host-or-port,index-or-null,type-or-null,id-or-null,query-or-null,payload-or-null) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">perform a GET operation</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.query(host-or-port,index-or-null,type-or-null,query-or-null,payload-or-null) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">perform a SEARCH operation</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.getRaw(host-or-port,path,payload-or-null) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">perform a raw GET operation</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.postRaw(host-or-port,path,payload-or-null) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">perform a raw POST operation</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.post(host-or-port,index-or-null,type-or-null,query-or-null,payload-or-null) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">perform a POST operation</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.es.put(host-or-port,index-or-null,type-or-null,query-or-null,payload-or-null) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">perform a PUT operation</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_interacting_with_mongodb"><a class="link" href="#_interacting_with_mongodb">Interacting with MongoDB</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 60%;">
<col style="width: 40%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.mongodb.get(host-or-port,db-or-null,collection-or-null,query-or-null,[compatibleValues=true|false],skip-or-null,limit-or-null) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">perform a find operation on mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.mongodb.count(host-or-port,db-or-null,collection-or-null,query-or-null) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">perform a find operation on mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.mongodb.first(host-or-port,db-or-null,collection-or-null,query-or-null,[compatibleValues=true|false]) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">perform a first operation on mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.mongodb.find(host-or-port,db-or-null,collection-or-null,query-or-null,projection-or-null,sort-or-null,[compatibleValues=true|false],skip-or-null) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">perform a find,project,sort operation on mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.mongodb.insert(host-or-port,db-or-null,collection-or-null,list-of-maps)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">inserts the given documents into the mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.mongodb.delete(host-or-port,db-or-null,collection-or-null,list-of-maps)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">inserts the given documents into the mongodb collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.mongodb.update(host-or-port,db-or-null,collection-or-null,list-of-maps)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">inserts the given documents into the mongodb collection</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>If your documents have date fields or any other type that can be automatically converted by Neo4j, you need to set <strong>compatibleValues</strong> to true. These values will be converted according to Jackson databind default mapping.</p>
</div>
<div class="paragraph">
<p>Copy these jars into the plugins directory:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>bson-3.4.2.jar</p>
</li>
<li>
<p>mongo-java-driver-3.4.2.jar</p>
</li>
<li>
<p>mongodb-driver-3.4.2.jar</p>
</li>
<li>
<p>mongodb-driver-core-3.4.2.jar</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>You should be able to get them from <a href="https://mongodb.github.io/mongo-java-driver/">here</a>, and <a href="https://mvnrepository.com/artifact/org.mongodb/bson/3.4.2">here (BSON)</a> (via Download)</p>
</div>
<div class="paragraph">
<p>Or you get them locally from your gradle build of apoc.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>gradle copyRuntimeLibs
cp lib/mongodb*.jar lib/bson*.jar $NEO4J_HOME/plugins/</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.mongodb.first('mongodb://localhost:27017','test','test',{name:'testDocument'})</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you need automatic conversion of <strong>unpackable</strong> values then the cypher query will be:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.mongodb.first('mongodb://localhost:27017','test','test',{name:'testDocument'},true)</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_interacting_with_couchbase"><a class="link" href="#_interacting_with_couchbase">Interacting with Couchbase</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 60%;">
<col style="width: 40%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.couchbase.get(nodes, bucket, documentId) yield id, expiry, cas, mutationToken, content</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Retrieves a couchbase json document by its unique ID</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.couchbase.exists(nodes, bucket, documentId) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Check whether a couchbase json document with the given ID does exist</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.couchbase.insert(nodes, bucket, documentId, jsonDocument) yield id, expiry, cas, mutationToken, content</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Insert a couchbase json document with its unique ID</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.couchbase.upsert(nodes, bucket, documentId, jsonDocument) yield id, expiry, cas, mutationToken, content</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Insert or overwrite a couchbase json document with its unique ID</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.couchbase.append(nodes, bucket, documentId, jsonDocument) yield id, expiry, cas, mutationToken, content</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Append a couchbase json document to an existing one</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.couchbase.prepend(nodes, bucket, documentId, jsonDocument) yield id, expiry, cas, mutationToken, content</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Prepend a couchbase json document to an existing one</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.couchbase.remove(nodes, bucket, documentId) yield id, expiry, cas, mutationToken, content</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Remove the couchbase json document identified by its unique ID</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.couchbase.replace(nodes, bucket, documentId, jsonDocument) yield id, expiry, cas, mutationToken, content</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Replace the content of the couchbase json document identified by its unique ID.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.couchbase.query(nodes, bucket, statement) yield queryResult</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Executes a plain un-parameterized N1QL statement.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.couchbase.posParamsQuery(nodes, bucket, statement, params) yield queryResult</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Executes a N1QL statement with positional parameters.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.couchbase.namedParamsQuery(nodes, bucket, statement, paramNames, paramValues) yield queryResult</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Executes a N1QL statement with named parameters.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Copy these jars into the plugins directory:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>mvn dependency:copy-dependencies
cp target/dependency/java-client-2.3.1.jar target/dependency/core-io-1.3.1.jar target/dependency/rxjava-1.1.5.jar $NEO4J_HOME/plugins/</pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.couchbase.get(['localhost'], 'default', 'artist:vincent_van_gogh')</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_streaming_data_to_gephi_2"><a class="link" href="#_streaming_data_to_gephi_2">Streaming Data to Gephi</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.gephi.add(url-or-key, workspace, data, weightproperty, ['exportproperty'])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">streams provided data to Gephi</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_creating_data"><a class="link" href="#_creating_data">Creating Data</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.node(['Label'], {key:value,&#8230;&#8203;})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">create node with dynamic labels</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.nodes(['Label'], [{key:value,&#8230;&#8203;}])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">create multiple nodes with dynamic labels</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.addLabels( [node,id,ids,nodes], ['Label',&#8230;&#8203;])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">adds the given labels to the node or nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.removeLabels( [node,id,ids,nodes], ['Label',&#8230;&#8203;])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">removes the given labels from the node or nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.setProperty( [node,id,ids,nodes], key, value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sets the given property on the node(s)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.setProperties( [node,id,ids,nodes], [keys], [values])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sets the given property on the nodes(s)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.setRelProperty( [rel,id,ids,rels], key, value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sets the given property on the relationship(s)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.setRelProperties( [rel,id,ids,rels], [keys], [values])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sets the given property on the relationship(s)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.relationship(person1,'KNOWS',{key:value,&#8230;&#8203;}, person2)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">create relationship with dynamic rel-type</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.uuids(count) YIELD uuid, row</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates count UUIDs</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.nodes.link([nodes],'REL_TYPE')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a linked list of nodes from first to last</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_paths"><a class="link" href="#_paths">Paths</a></h3>
<div class="paragraph">
<p>Functions to create, combine and split paths</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.path.create(startNode,[rels])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a path instance of the given elements</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.path.slice(path, [offset], [length])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a sub-path with the given offset and length</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.path.combine(path1, path2)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">combines the paths into one if the connecting node matches</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.path.elements(path)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a list of node-relationship-node-&#8230;&#8203;</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_virtual_nodes_rels_2"><a class="link" href="#_virtual_nodes_rels_2">Virtual Nodes/Rels</a></h3>
<div class="paragraph">
<p>Virtual Nodes and Relationships don&#8217;t exist in the graph, they are only returned to the UI/user for representing a graph projection.
They can be visualized or processed otherwise.
Please note that they have negative id&#8217;s.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.vNode(['Label'], {key:value,&#8230;&#8203;}) YIELD node</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.create.vNode(['Label'], {key:value,&#8230;&#8203;})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.vNodes(['Label'], [{key:value,&#8230;&#8203;}])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns virtual nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.vRelationship(nodeFrom,'KNOWS',{key:value,&#8230;&#8203;}, nodeTo) YIELD rel</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.create.vRelationship(nodeFrom,'KNOWS',{key:value,&#8230;&#8203;}, nodeTo)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.vPattern({_labels:['LabelA'],key:value},'KNOWS',{key:value,&#8230;&#8203;}, {_labels:['LabelB'],key:value})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual pattern</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.create.vPatternFull(['LabelA'],{key:value},'KNOWS',{key:value,&#8230;&#8203;},['LabelB'],{key:value})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a virtual pattern</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.nodes.group([labels],[properties],[{node-aggregation},{rel-aggregation]) yield nodes, relationships</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Group all nodes and their relationships by given keys, create virtual nodes and relationships for the summary information, you can provide an aggregations map for nodes and rels [{kids:'sum',age:['min','max','avg'],gender:'collect'},{<code>*</code>,'count'}]</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_virtual_graph_2"><a class="link" href="#_virtual_graph_2">Virtual Graph</a></h3>
<div class="paragraph">
<p>Create a graph object (map) from information that&#8217;s passed in.
It&#8217;s basic structure is: <code>{name:"Name",properties:{properties},nodes:[nodes],relationships:[relationships]}</code></p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.from(data,'name',{properties}) yield graph</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing it tries its best to extract the graph information from the data you pass in</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.fromData([nodes],[relationships],'name',{properties})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.fromPaths(path,'name',{properties})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.fromPaths([paths],'name',{properties})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.fromDB('name',{properties})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.graph.fromCypher('statement',{params},'name',{properties})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a virtual graph object for later processing</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_generating_graphs"><a class="link" href="#_generating_graphs">Generating Graphs</a></h3>
<div class="paragraph">
<p>Generate undirected (random direction) graphs with semi-real random distributions based on theoretical models.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.generate.er(noNodes, noEdges, 'label', 'type')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">generates a graph according to Erdos-Renyi model (uniform)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.generate.ws(noNodes, degree, beta, 'label', 'type')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">generates a graph according to Watts-Strogatz model (clusters)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.generate.ba(noNodes, edgesPerNode, 'label', 'type')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">generates a graph according to Barabasi-Albert model (preferential attachment)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.generate.complete(noNodes, 'label', 'type')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">generates a complete graph (all nodes connected to all other nodes)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.generate.simple([degrees], 'label', 'type')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">generates a graph with the given degree distribution</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Example</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.generate.ba(1000, 2, 'TestLabel', 'TEST_REL_TYPE')
CALL apoc.generate.ws(1000, null, null, null)
CALL apoc.generate.simple([2,2,2,2], null, null)</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_warmup"><a class="link" href="#_warmup">Warmup</a></h3>
<div class="paragraph">
<p>(thanks @SaschaPeukert)</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.warmup.run([loadProperties],[loadDynamicProperties])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Warmup the node, relationship, relationship-group page-caches by loading one page at a time, optionally load property-records and dynamic-properties</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_monitoring"><a class="link" href="#_monitoring">Monitoring</a></h3>
<div class="paragraph">
<p>(thanks @ikwattro)</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.monitor.ids</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">node and relationships-ids in total and in use</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.monitor.kernel</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">store information such as kernel version, start time, read-only, database-name, store-log-version etc.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.monitor.store</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">store size information for the different types of stores</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.monitor.tx</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">number of transactions total,opened,committed,concurrent,rolled-back,last-tx-id</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.monitor.locks(minWaitTime long)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">db locking information such as avertedDeadLocks, lockCount, contendedLockCount and contendedLocks etc. (enterprise)</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_cypher_execution"><a class="link" href="#_cypher_execution">Cypher Execution</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.cypher.run(fragment, params) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">executes reading fragment with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.cypher.runFirstColumn(statement, params, [expectMultiplevalues])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">function that executes statement with given parameters returning first column only, if expectMultipleValues is true will collect results into a list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.cypher.runFile(file or url,{config}) yield row, result</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">runs each statement in the file, all semicolon separated - currently no schema operations</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.cypher.runFiles([files or urls],{config}) yield row, result</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">runs each statement in the files, all semicolon separated</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.cypher.runSchemaFile(file or url,{config}) - allows only schema operations, runs each schema statement in the file, all semicolon separated</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">CALL apoc.cypher.runSchemaFiles([files or urls],{config}) - allows only schema operations, runs each schema statement in the files, all semicolon separated</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.cypher.runMany('cypher;\nstatements;',{params},{config})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">runs each semicolon separated statement and returns summary - currently no schema operations</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.cypher.mapParallel(fragment, params, list-to-parallelize) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">executes fragment in parallel batches with the list segments being assigned to _</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.cypher.doIt(fragment, params) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">executes writing fragment with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.cypher.runTimeboxed('cypherStatement',{params}, timeout)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">abort statement after timeout millis if not finished</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_conditional_cypher_execution_2"><a class="link" href="#_conditional_cypher_execution_2">Conditional Cypher Execution</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.when(condition, ifQuery, elseQuery:'', params:{}) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">based on the conditional, executes read-only ifQuery or elseQuery with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.do.when(condition, ifQuery, elseQuery:'', params:{}) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">based on the conditional, executes writing ifQuery or elseQuery with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.case([condition, query, condition, query, &#8230;&#8203;], elseQuery:'', params:{}) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">given a list of conditional / read-only query pairs, executes the query associated with the first conditional evaluating to true (or the else query if none are true) with the given parameters</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.do.case([condition, query, condition, query, &#8230;&#8203;], elseQuery:'', params:{}) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">given a list of conditional / writing query pairs, executes the query associated with the first conditional evaluating to true (or the else query if none are true) with the given parameters</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_triggers_2"><a class="link" href="#_triggers_2">Triggers</a></h3>
<div class="paragraph">
<p>Enable <code>apoc.trigger.enabled=true</code> in <code>$NEO4J_HOME/config/neo4j.conf</code> first.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.trigger.add(name, statement, selector) yield name, statement, installed</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">add a trigger statement under a name, in the statement you can use {createdNodes}, {deletedNodes} etc., the selector is {phase:'before/after/rollback'} returns previous and new trigger information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.trigger.remove(name) yield name, statement, installed</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">remove previously added trigger, returns trigger information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.trigger.list() yield name, statement, installed</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">update and list all installed triggers</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.trigger.pause(name)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">it pauses the trigger</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.trigger.resume(name)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">it resumes the paused trigger</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Helper Functions</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.trigger.nodesByLabel({assignedLabels},'Label')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">function to filter labelEntries by label, to be used within a trigger statement with {assignedLabels} and {removedLabels} {phase:'before/after/rollback'} returns previous and new trigger information</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.trigger.propertiesByKey({assignedNodeProperties},'key')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">function to filter propertyEntries by property-key, to be used within a trigger statement with {assignedNode/RelationshipProperties} and {removedNode/RelationshipProperties}. Returns [{old,new,key,node,relationship}]</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_job_management"><a class="link" href="#_job_management">Job Management</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.periodic.commit(statement, params)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">repeats an batch update statement until it returns 0, this procedure is blocking</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.periodic.list()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">list all jobs</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.periodic.submit('name',statement)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">submit a one-off background statement</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.periodic.schedule('name',statement,repeat-time-in-seconds)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">submit a repeatedly-called background statement</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.periodic.countdown('name',statement,delay-in-seconds)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">submit a repeatedly-called background statement until it returns 0</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.periodic.rock_n_roll(statementIteration, statementAction, batchSize) YIELD batches, total</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">iterate over first statement and apply action statement with given transaction batch size. Returns to numeric values holding the number of batches and the number of total processed rows. E.g.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.periodic.iterate('statement returning items', 'statement per item', {batchSize:1000,parallel:true,retries:3,iterateList:true}) YIELD batches, total</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">run the second statement for each item returned by the first statement. Returns number of batches and total processed rows</p></td>
</tr>
</tbody>
</table>
<div class="ulist">
<ul>
<li>
<p>there are also static methods <code>Jobs.submit</code>, and <code>Jobs.schedule</code> to be used from other procedures</p>
</li>
<li>
<p>jobs list is checked / cleared every 10s for finished jobs</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="title">copies over the <code>name</code> property of each person to <code>lastname</code></div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.periodic.rock_n_roll('match (p:Person) return id(p) as id_p', 'MATCH (p) where id(p)={id_p} SET p.lastname =p.name', 20000)</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_graph_refactoring_2"><a class="link" href="#_graph_refactoring_2">Graph Refactoring</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.cloneNodes([node1,node2,&#8230;&#8203;],[withRelationships=false],[skipProperties=[]])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">clone nodes with their labels and properties</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.cloneNodesWithRelationships([node1,node2,&#8230;&#8203;])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">deprecated</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.mergeNodes([node1,node2],{config})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">merge nodes onto first in list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.mergeRelationships([rel1,rel2,&#8230;&#8203;],{config})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">merge relationships onto first in list. Config param is <code>properties</code>.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.to(rel, endNode)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">redirect relationship to use new end-node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.from(rel, startNode)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">redirect relationship to use new start-node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.invert(rel)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">inverts relationship direction</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.setType(rel, 'NEW-TYPE')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">change relationship-type</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.extractNode([rel1,rel2,&#8230;&#8203;], [labels], 'OUT','IN')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">extract node from relationships</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.collapseNode([node1,node2],'TYPE')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">collapse nodes with 2 rels to relationship, node with one rel becomes self-relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.normalizeAsBoolean(entity, propertyKey, true_values, false_values)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">normalize/convert a property to be boolean</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.categorize(node, propertyKey, type, outgoing, label)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">turn each unique propertyKey into a category node and connect to it</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.rename.label(oldLabel, newLabel, [nodes])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">rename a label from 'oldLabel' to 'newLabel' for all nodes. If 'nodes' is provided renaming is applied to this set only</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.rename.type(oldType, newType, [rels])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">rename all relationships with type 'oldType' to 'newType'. If 'rels' is provided renaming is applied to this set only</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.rename.nodeProperty(oldName, newName, [nodes])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">rename all node&#8217;s property from 'oldName' to 'newName'. If 'nodes' is provided renaming is applied to this set only</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.refactor.rename.typeProperty(oldName, newName, [rels])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">rename all relationship&#8217;s property from 'oldName' to 'newName'. If 'rels' is provided renaming is applied to this set only</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>On mergeRelationship with config properties you can choose from 3 different management:
* "overwrite" : if there is the same property in more relationship, in the new one will have the last relationship&#8217;s property value
* "discard" : if there is the same property in more relationship, the new one will have the first relationship&#8217;s property value
* "combine" : if there is the same property in more relationship, the new one a value&#8217;s array with all relationships' values</p>
</div>
<div class="paragraph">
<p>TODO:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>merge nodes by label + property</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_spatial_2"><a class="link" href="#_spatial_2">Spatial</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.spatial.geocode('address') YIELD location, latitude, longitude, description, osmData</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">look up geographic location of location from openstreetmap geocoding service</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.spatial.sortPathsByDistance(Collection&lt;Path&gt;) YIELD path, distance</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sort a given collection of paths by geographic distance based on lat/long properties on the path nodes</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_helpers"><a class="link" href="#_helpers">Helpers</a></h3>
<div class="sect3">
<h4 id="_aggregation_functions"><a class="link" href="#_aggregation_functions">Aggregation Functions</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.agg.nth(value,offset)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns non-null value of nth row (or -1 for last) offset is 0 based</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.agg.first(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns first non-null value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.agg.last(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns last non-null value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.agg.slice(value, start, length)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns subset of non-null values, start is 0 based and length can be -1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.agg.product(number)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns given product for non-null values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.agg.median(number)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns median for non-null numeric values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.agg.percentiles(value,[percentiles = 0.5,0.75,0.9,0.95,0.99])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns given percentiles for integer values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.agg.statistics(value,[percentiles = 0.5,0.75,0.9,0.95,0.99])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns numeric statistics (percentiles, min,minNonZero,max,total,mean,stdev) for values</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_static_value_storage"><a class="link" href="#_static_value_storage">Static Value Storage</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.static.get(name)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns statically stored value from config (apoc.static.&lt;key&gt;) or server lifetime storage</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.static.getAll(prefix)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns statically stored values from config (apoc.static.&lt;prefix&gt;) or server lifetime storage</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.static.set(name, value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">stores value under key for server livetime storage, returns previously stored or configured value</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_conversion_functions"><a class="link" href="#_conversion_functions">Conversion Functions</a></h4>
<div class="paragraph">
<p>Sometimes type information gets lost, these functions help you to coerce an "Any" value to the concrete type</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toString(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">tries it&#8217;s best to convert the value to a string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toMap(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">tries it&#8217;s best to convert the value to a map</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toList(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">tries it&#8217;s best to convert the value to a list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toBoolean(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">tries it&#8217;s best to convert the value to a boolean</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toNode(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">tries it&#8217;s best to convert the value to a node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toRelationship(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">tries it&#8217;s best to convert the value to a relationship</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toSet(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">tries it&#8217;s best to convert the value to a set</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toFloat(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">tries it&#8217;s best to convert the value to a floating point value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.convert.toInteger(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">tries it&#8217;s best to convert the value to a integer value</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_map_functions"><a class="link" href="#_map_functions">Map Functions</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.fromNodes(label, property)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates map from nodes with this label grouped by property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.fromPairs([[key,value],[key2,value2],&#8230;&#8203;])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates map from list with key-value pairs</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.fromLists([keys],[values])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates map from a keys and a values list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.fromValues([key,value,key1,value1])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates map from alternating keys and values in a list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.merge({first},{second}) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates map from merging the two source maps</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.mergeList([{maps}]) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">merges all maps in the list into one</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.setKey(map,key,value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns the map with the value for this key added or replaced</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.removeKey(map,key)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns the map with the key removed</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.removeKeys(map,[keys])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns the map with the keys removed</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.clean(map,[keys],[values]) yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">removes the keys and values (e.g. null-placeholders) contained in those lists, good for data cleaning from CSV/JSON</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.groupBy([maps/nodes/relationships],'key') yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a map of the list keyed by the given property, with single values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.groupByMulti([maps/nodes/relationships],'key') yield value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates a map of the list keyed by the given property, with list values</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.sortedProperties(map, ignoreCase:true)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a list of key/value list pairs, with pairs sorted by keys alphabetically, with optional case sensitivity</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.map.updateTree(tree,key,<a id="value"></a>)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns map - adds the {data} map on each level of the nested tree, where the key-value pairs match</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_collection_functions"><a class="link" href="#_collection_functions">Collection Functions</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.sum([0.5,1,2.3])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sum of all values in a list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.avg([0.5,1,2.3])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">avg of all values in a list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.min([0.5,1,2.3])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">minimum of all values in a list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.max([0.5,1,2.3])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">maximum of all values in a list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.sumLongs([1,3,3])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sums all numeric values in a list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.partition(list,batchSize)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">partitions a list into sublists of <code>batchSize</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.zip([list1],[list2])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">all values in a list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.pairs([1,2,3]) YIELD value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">[1,2],[2,3],[3,null]</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.pairsMin([1,2,3]) YIELD value</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">[1,2],[2,3]</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.toSet([list])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a unique list backed by a set</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.sort(coll)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sort on Collections</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.sortNodes([nodes], 'name')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sort nodes by property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.sortMaps([maps], 'key')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sort maps by map key</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.reverse(coll)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns the reversed list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.contains(coll, value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">optimized contains operation (using a HashSet) (returns single row or not)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.containsAll(coll, values)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">optimized contains-all operation (using a HashSet) (returns single row or not)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.containsSorted(coll, value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">optimized contains on a sorted list operation (Collections.binarySearch) (returns single row or not)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.containsAllSorted(coll, value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">optimized contains-all on a sorted list operation (Collections.binarySearch) (returns single row or not)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.union(first, second)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates the distinct union of the 2 lists</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.subtract(first, second)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns unique set of first list with all elements of second list removed</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.removeAll(first, second)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns first list with all elements of second list removed</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.intersection(first, second)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns the unique intersection of the two lists</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.disjunction(first, second)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns the disjunct set of the two lists</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.unionAll(first, second)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">creates the full union with duplicates of the two lists</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.split(list,value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">splits collection on given values rows of lists, value itself will not be part of resulting lists</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.indexOf(coll, value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">position of value in the list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.shuffle(coll)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns the shuffled list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.randomItem(coll)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a random item from the list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.randomItems(coll, itemCount, allowRepick: false)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a list of <code>itemCount</code> random items from the list, optionally allowing picked elements to be picked again</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.containsDuplicates(coll)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns true if a collection contains duplicate elements</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.duplicates(coll)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a list of duplicate items in the collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.duplicatesWithCount(coll)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a list of duplicate items in the collection and their count, keyed by <code>item</code> and <code>count</code> (e.g., <code>[{item: xyz, count:2}, {item:zyx, count:5}]</code>)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.occurrences(coll, item)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns the count of the given item in the collection</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.frequencies(coll)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a list of frequencies of the items in the collection, keyed by <code>item</code> and <code>count</code> (e.g., <code>[{item: xyz, count:2}, {item:zyx, count:5}, {item:abc, count:1}]</code>)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.sortMulti</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sort list of maps by several sort fields (ascending with ^ prefix) and optionally applies limit and skip</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.flatten</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">flattens a nested list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.combinations(coll, minSelect, maxSelect:minSelect)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Returns collection of all combinations of list elements of selection size between minSelect and maxSelect (default:minSelect), inclusive</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.coll.elements(list,limit,offset) yield _1,_2,..,_10,_1s,_2i,_3f,_4m,_5l,_6n,_7r,_8p</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">deconstruct subset of mixed list into identifiers of the correct type</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.set(coll, index, value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">set index to value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.insert(coll, index, value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">insert value at index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.insertAll(coll, index, values)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">insert values at index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.coll.remove(coll, index, [length=1])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">remove range of values from index to length</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_lookup_and_manipulation_procedures"><a class="link" href="#_lookup_and_manipulation_procedures">Lookup and Manipulation Procedures</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.nodes.get(node|nodes|id|[ids])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">quickly returns all nodes with these ids</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.get.rels(rel|id|[ids])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">quickly returns all relationships with these ids</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.nodes.delete(node|nodes|id|[ids])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">quickly delete all nodes with these ids</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_node_functions"><a class="link" href="#_node_functions">Node Functions</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.nodes.isDense(node)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns true if it is a dense node</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.nodes.connected(start, end, rel-direction-pattern)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns true when the node is connected to the other node, optimized for dense nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.node.relationship.exists(node, rel-direction-pattern)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns true when the node has the relationships of the pattern</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.node.relationship.types(node, rel-direction-pattern)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a list of distinct relationship types</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.node.degree(node, rel-direction-pattern)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns total degrees of the given relationships in the pattern, can use <code>'&gt;'</code> or <code>'&lt;'</code> for all outgoing or incoming relationships</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.create.uuid()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a UUID string</p></td>
</tr>
</tbody>
</table>
<div class="sect4">
<h5 id="_rel_direction_pattern_syntax"><a class="link" href="#_rel_direction_pattern_syntax">rel-direction-pattern syntax:</a></h5>
<div class="paragraph">
<p><code>[&lt;]RELATIONSHIP_TYPE1[&gt;]|[&lt;]RELATIONSHIP_TYPE2[&gt;]|&#8230;&#8203;</code></p>
</div>
<div class="paragraph">
<p>Example: <code>'FRIEND|MENTORS&gt;|&lt;REPORTS_TO'</code> will match to :FRIEND relationships in either direction, outgoing :MENTORS relationships, and incoming :REPORTS_TO relationships.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_math_functions"><a class="link" href="#_math_functions">Math Functions</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.math.round(value,[precision=0],mode=[HALF_UP,CEILING,FLOOR,UP,DOWN,HALF_EVEN,HALF_DOWN,DOWN,UNNECESSARY])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">rounds value with optionally given precision (default 0) and optional rounding mode (default HALF_UP)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.math.maxLong()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the maximum value a long can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.math.minLong()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the minimum value a long can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.math.maxDouble()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the largest positive finite value of type double</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.math.minDouble()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the smallest positive nonzero value of type double</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.math.maxInt()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the maximum value a int can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.math.minInt()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the minimum value a int can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.math.maxByte()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the maximum value a byte can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.math.minByte()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the minimum value a byte can have</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.number.romanToArabic(romanNumber)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">convert roman numbers to arabic</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.number.arabicToRoman(number)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">convert arabic numbers to roman</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_text_functions"><a class="link" href="#_text_functions">Text Functions</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.replace(text, regex, replacement)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">replace each substring of the given string that matches the given regular expression with the given replacement.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.regexGroups(text, regex)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns an array containing a nested array for each match. The inner array contains all match groups.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.join(['text1','text2',&#8230;&#8203;], delimiter)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">join the given strings with the given delimiter.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.format(text,[params])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sprintf format the string with the params given</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.lpad(text,count,delim)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">left pad the string to the given width</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.rpad(text,count,delim)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">right pad the string to the given width</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.random(length, [valid])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">returns a random string to the specified length</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.capitalize(text)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">capitalise the first letter of the word</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.capitalizeAll(text)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">capitalise the first letter of every word in the text</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.decapitalize(text)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">decapitalize the first letter of the word</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.decapitalizeAll(text)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">decapitalize the first letter of all words</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.swapCase(text)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Swap the case of a string</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.camelCase(text)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Convert a string to camelCase</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.upperCamelCase(text)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Convert a string to UpperCamelCase</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.snakeCase(text)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Convert a string to snake-case</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.toUpperCase(text)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Convert a string to UPPER_CASE</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.charAt(text, index)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Returns the decimal value of the character at the given index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.code(codepoint)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Returns the unicode character of the given codepoint</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.hexCharAt(text, index)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Returns the hex value string of the character at the given index</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.hexValue(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Returns the hex value string of the given value</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.byteCount(text,[charset])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return size of text in bytes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.bytes(text,[charset]) - return bytes of the text</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.text.toCypher(value, {skipKeys,keepKeys,skipValues,keepValues,skipNull,node,relationship,start,end})</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_data_extraction"><a class="link" href="#_data_extraction">Data Extraction</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.data.url('url') as {protocol,user,host,port,path,query,file,anchor}</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">turn URL into map structure</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.data.email('email_address') as {personal,user,domain}</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">extract the personal name, user and domain as a map (needs javax.mail jar)</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.data.domain(email_or_url)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><strong>deprecated</strong> returns domain part of the value</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_text_similarity_functions"><a class="link" href="#_text_similarity_functions">Text Similarity Functions</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.distance(text1, text2)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">compare the given strings with the StringUtils.distance(text1, text2) method</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.sorensenDiceSimilarity(text1, text2)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">compare the given strings with the Sørensen–Dice coefficient formula, assuming an English locale</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.sorensenDiceSimilarityWithLanguage(text1, text2, languageTag)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">compare the given strings with the Sørensen–Dice coefficient formula, with the provided IETF language tag</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.fuzzyMatch(text1, text2)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">check if 2 words can be matched in a fuzzy way. Depending on the length of the String it will allow more characters that needs to be edited to match the second String.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_phonetic_comparison_functions"><a class="link" href="#_phonetic_comparison_functions">Phonetic Comparison Functions</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.phonetic(value)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Compute the US_ENGLISH phonetic soundex encoding of all words of the text value which can be a single string or a list of strings</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.clean(text)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">strip the given string of everything except alpha numeric characters and convert it to lower case.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.compareCleaned(text1, text2)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">compare the given strings stripped of everything except alpha numeric characters converted to lower case.</p></td>
</tr>
</tbody>
</table>
<table class="tableblock frame-all grid-all spread">
<caption class="title">Table 9. Procedure</caption>
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.text.phoneticDelta(text1, text2) yield phonetic1, phonetic2, delta</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Compute the US_ENGLISH soundex character difference between two given strings</p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_utilities"><a class="link" href="#_utilities">Utilities</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.util.sha1([values])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">computes the sha1 of the concatenation of all string values of the list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.util.md5([values])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">computes the md5 of the concatenation of all string values of the list</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.util.sleep({duration})</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sleeps for &lt;duration&gt; millis, transaction termination is honored</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.util.validate(predicate, message,[params])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">raises exception if prediate evaluates to true</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_config"><a class="link" href="#_config">Config</a></h3>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.config.list</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Lists the Neo4j configuration as key,value table</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.config.map</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Lists the Neo4j configuration as map</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_time_to_live_ttl"><a class="link" href="#_time_to_live_ttl">Time to Live (TTL)</a></h3>
<div class="paragraph">
<p>Enable TTL with setting in <code>neo4j.conf</code> : <code>apoc.ttl.enabled=true</code></p>
</div>
<div class="paragraph">
<p>There are some convenience procedures to expire nodes.</p>
</div>
<div class="paragraph">
<p>You can also do it yourself by running</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">SET n:TTL
SET n.ttl = timestamp() + 3600</code></pre>
</div>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.date.expire.in(node,time,'time-unit')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">expire node in given time-delta by setting :TTL label and <code>ttl</code> property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CALL apoc.date.expire(node,time,'time-unit')</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">expire node at given time by setting :TTL label and <code>ttl</code> property</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Optionally set <code>apoc.ttl.schedule=5</code> as repeat frequency.</p>
</div>
</div>
<div class="sect2">
<h3 id="_date_time_support"><a class="link" href="#_date_time_support">Date/time Support</a></h3>
<div class="paragraph">
<p>(thanks @tkroman)</p>
</div>
<div class="sect3">
<h4 id="_conversion_functions_between_formatted_dates_and_timestamps"><a class="link" href="#_conversion_functions_between_formatted_dates_and_timestamps">Conversion Functions between formatted dates and timestamps</a></h4>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.date.parse('2015/03/25 03:15:59',['ms'/'s'], ['yyyy/MM/dd HH:mm:ss'])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">same as previous, but accepts custom datetime format</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.date.format(12345, ['ms'/'s'], ['yyyy/MM/dd HH:mm:ss'])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">the same as previous, but accepts custom datetime format</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.date.systemTimezone()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return the system timezone display format string</p></td>
</tr>
</tbody>
</table>
<div class="ulist">
<ul>
<li>
<p>possible unit values: <code>ms,s,m,h,d</code> and their long forms <code>millis,milliseconds,seconds,minutes,hours,days</code>.</p>
</li>
<li>
<p>possible time zone values: Either an abbreviation such as <code>PST</code>, a full name such as <code>America/Los_Angeles</code>, or a custom ID such as <code>GMT-8:00</code>. Full names are recommended. You can view a list of full names in <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">this Wikipedia page</a>.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_conversion_of_timestamps_between_different_time_units_2"><a class="link" href="#_conversion_of_timestamps_between_different_time_units_2">Conversion of timestamps between different time units</a></h4>
<div class="ulist">
<ul>
<li>
<p><code>apoc.date.convert(12345, 'ms', 'd')</code> convert a timestamp in one time unit into one of a different time unit</p>
</li>
<li>
<p>possible unit values: <code>ms,s,m,h,d</code> and their long forms.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_adding_subtracting_time_unit_values_to_timestamps_2"><a class="link" href="#_adding_subtracting_time_unit_values_to_timestamps_2">Adding/subtracting time unit values to timestamps</a></h4>
<div class="ulist">
<ul>
<li>
<p><code>apoc.date.add(12345, 'ms', -365, 'd')</code> given a timestamp in one time unit, adds a value of the specified time unit</p>
</li>
<li>
<p>possible unit values: <code>ms,s,m,h,d</code> and their long forms.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_reading_separate_datetime_fields_2"><a class="link" href="#_reading_separate_datetime_fields_2">Reading separate datetime fields</a></h4>
<div class="paragraph">
<p>Splits date (optionally, using given custom format) into fields returning a map from field name to its value.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>apoc.date.fields('2015-03-25 03:15:59')</code></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_reading_single_datetime_field_from_utc_epoch_2"><a class="link" href="#_reading_single_datetime_field_from_utc_epoch_2">Reading single datetime field from UTC epoch</a></h4>
<div class="paragraph">
<p>Extracts the value of one field from a datetime epoch.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>apoc.date.field(12345)</code></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_current_timestamp_2"><a class="link" href="#_current_timestamp_2">Current timestamp</a></h3>
<div class="paragraph">
<p><code>apoc.date.currentTimestamp()</code> provides the System.currentTimeMillis which is current throughout transaction execution compared to Cypher&#8217;s timestamp() function which does not update within a transaction</p>
</div>
</div>
<div class="sect2">
<h3 id="_bitwise_operations"><a class="link" href="#_bitwise_operations">Bitwise operations</a></h3>
<div class="paragraph">
<p>Provides a wrapper around the java bitwise operations.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 100%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bitwise.op(a long, "operation", b long ) as &lt;identifier&gt;</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>examples</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">operator</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">name</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">example</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">result</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">a &amp; b</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">AND</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bitwise.op(60,"&amp;",13)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">12</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">a | b</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">OR</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bitwise.op(60,"|",13)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">61</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">a ^ b</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">XOR</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bitwise.op(60,"&amp;",13)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">49</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">~a</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">NOT</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bitwise.op(60,"&amp;",0)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">-61</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">a &lt;&lt; b</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">LEFT SHIFT</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bitwise.op(60,"&lt;&lt;",2)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">240</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">a &gt;&gt; b</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">RIGHT SHIFT</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bitwise.op(60,"&gt;&gt;",2)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">15</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">a &gt;&gt;&gt; b</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UNSIGNED RIGHT SHIFT</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">apoc.bitwise.op(60,"&gt;&gt;&gt;",2)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">15</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_path_expander"><a class="link" href="#_path_expander">Path Expander</a></h3>
<div class="paragraph">
<p>(thanks @keesvegter)</p>
</div>
<div class="paragraph">
<p>The apoc.path.expand procedure makes it possible to do variable length path traversals where you can specify the direction of the relationship per relationship type and a list of Label names which act as a "whitelist" or a "blacklist" or define end nodes for the expansion. The procedure will return a list of Paths in a variable name called "path".</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.path.expand(startNode &lt;id&gt;|Node, relationshipFilter, labelFilter, minDepth, maxDepth ) yield path as &lt;identifier&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">expand from given nodes(s) taking the provided restrictions into account</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Variations allow more configurable expansions, and expansions for more specific use cases:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.path.expandConfig(startNode &lt;id&gt;Node/list, {minLevel, maxLevel, relationshipFilter, labelFilter, bfs:true, uniqueness:'RELATIONSHIP_PATH', filterStartNode:true, limit, optional:false, endNodes, terminatorNodes, sequence, beginSequenceAtStart:true}) yield path</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">expand from given nodes(s) taking the provided restrictions into account</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.path.subgraphNodes(startNode &lt;id&gt;Node/list, {maxLevel, relationshipFilter, labelFilter, bfs:true, filterStartNode:true, limit, optional:false, endNodes, terminatorNodes, sequence, beginSequenceAtStart:true}) yield node</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">expand a subgraph from given nodes(s) taking the provided restrictions into account; returns all nodes in the subgraph</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.path.subgraphAll(startNode &lt;id&gt;Node/list, {maxLevel, relationshipFilter, labelFilter, bfs:true, filterStartNode:true, limit, endNodes, terminatorNodes, sequence, beginSequenceAtStart:true}) yield nodes, relationships</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">expand a subgraph from given nodes(s) taking the provided restrictions into account; returns the collection of subgraph nodes, and the collection of all relationships within the subgraph</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.path.spanningTree(startNode &lt;id&gt;Node/list, {maxLevel, relationshipFilter, labelFilter, bfs:true, filterStartNode:true, limit, optional:false, endNodes, terminatorNodes, sequence, beginSequenceAtStart:true}) yield path</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">expand a spanning tree from given nodes(s) taking the provided restrictions into account; the paths returned collectively form a spanning tree</p></td>
</tr>
</tbody>
</table>
<div class="sect3">
<h4 id="_relationship_filter_2"><a class="link" href="#_relationship_filter_2">Relationship Filter</a></h4>
<div class="paragraph">
<p>Syntax: <code>[&lt;]RELATIONSHIP_TYPE1[&gt;]|[&lt;]RELATIONSHIP_TYPE2[&gt;]|&#8230;&#8203;</code></p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">input</th>
<th class="tableblock halign-left valign-top">type</th>
<th class="tableblock halign-left valign-top">direction</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>LIKES&gt;</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>LIKES</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>OUTGOING</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>&lt;FOLLOWS</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FOLLOWS</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>INCOMING</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>KNOWS</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>KNOWS</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>BOTH</p>
</div></div></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_label_filter_2"><a class="link" href="#_label_filter_2">Label Filter</a></h4>
<div class="paragraph">
<p>Syntax: <code>[+-/&gt;]LABEL1|LABEL2|*|&#8230;&#8203;</code></p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">input</th>
<th class="tableblock halign-left valign-top">result</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>-Foe</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>blacklist filter - No node in the path will have a label in the blacklist.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>+Friend</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>whitelist filter - All nodes in the path must have a label in the whitelist (exempting termination and end nodes, if using those filters).
If no whitelist operator is present, all labels are considered whitelisted.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>/Friend</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>termination filter - Only return paths up to a node of the given labels, and stop further expansion beyond it.
Termination nodes do not have to respect the whitelist. Termination filtering takes precedence over end node filtering.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>&gt;Friend</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>end node filter - Only return paths up to a node of the given labels, but continue expansion to match on end nodes beyond it.
End nodes do not have to respect the whitelist to be returned, but expansion beyond them is only allowed if the node has a label in the whitelist.</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<div class="title">Syntax Changes</div>
<p>As of APOC 3.1.3.x multiple label filter operations are allowed.
In prior versions, only one type of operation is allowed in the label filter (<code>+</code> or <code>-</code> or <code>/</code> or <code>&gt;</code>, never more than one).</p>
</div>
<div class="paragraph">
<p>With APOC 3.2.x.x, label filters will no longer apply to starting nodes of the expansion by default, but this can be toggled with the <code>filterStartNode</code> config parameter.</p>
</div>
<div class="paragraph">
<p>With the APOC releases in January 2018, some behavior has changed in the label filters:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">filter</th>
<th class="tableblock halign-left valign-top">changed behavior</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>No filter</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Now indicates the label is whitelisted, same as if it were prefixed with <code>+</code>.
Previously, a label without a filter symbol reused the previously used symbol.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code><code>&gt;</code> (end node filter)</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>The label is additionally whitelisted, so expansion will always continue beyond an end node (unless prevented by the blacklist).
Previously, expansion would only continue if allowed by the whitelist and not disallowed by the blacklist.
This also applies at a depth below <code>minLevel</code>, allowing expansion to continue.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code><code>/</code> (termination filter)</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>When at depth below <code>minLevel</code>, expansion is allowed to continue and no pruning will take place (unless prevented by the blacklist).
Previously, expansion would only continue if allowed by the whitelist and not disallowed by the blacklist.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>All filters</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><code>*</code> is allowed as a standin for all labels.
Additionally, compound labels are supported (like <code>Person:Manager</code>), and only apply to nodes with all of those labels present (order agnositic).</p>
</div></div></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_sequences_2"><a class="link" href="#_sequences_2">Sequences</a></h4>
<div class="paragraph">
<p>Introduced in the February 2018 APOC releases, path expander procedures can expand on repeating sequences of labels, relationship types, or both.</p>
</div>
<div class="paragraph">
<p>If only using label sequences, just use the <code>labelFilter</code>, but use commas to separate the filtering for each step in the repeating sequence.</p>
</div>
<div class="paragraph">
<p>If only using relationship sequences, just use the <code>relationshipFilter</code>, but use commas to separate the filtering for each step of the repeating sequence.</p>
</div>
<div class="paragraph">
<p>If using sequences of both relationships and labels, use the <code>sequence</code> parameter.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
<col style="width: 20%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Usage</th>
<th class="tableblock halign-left valign-top">config param</th>
<th class="tableblock halign-left valign-top">description</th>
<th class="tableblock halign-left valign-top">syntax</th>
<th class="tableblock halign-left valign-top">explanation</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>label sequences only</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>labelFilter</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Same syntax and filters, but uses commas (<code>,</code>) to separate the filters for each step in the sequence.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>labelFilter:'Post|-Blocked,Reply,&gt;Admin'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Start node must be a :Post node that isn&#8217;t :Blocked, next node must be a :Reply, and the next must be an :Admin, then repeat if able. Only paths ending with the <code>:Admin</code> node in that position of the sequence will be returned.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>relationship sequences only</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>relationshipFilter</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Same syntax, but uses commas (<code>,</code>) to separate the filters for each relationship traversal in the sequence.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>relationshipFilter:'NEXT&gt;,&lt;FROM,POSTED&gt;|REPLIED&gt;'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Expansion will first expand <code>NEXT&gt;</code> from the start node, then <code>&lt;FROM</code>, then either <code>POSTED&gt;</code> or <code>REPLIED&gt;</code>, then repeat if able.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>sequences of both labels and relationships</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sequence</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>A string of comma-separated alternating label and relationship filters, for each step in a repeating sequence. The sequence should begin with a label filter, and end with a relationship filter. If present, <code>labelFilter</code>, and <code>relationshipFilter</code> are ignored, as this takes priority.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sequence:'Post|-Blocked, NEXT&gt;, Reply, &lt;FROM, &gt;Admin, POSTED&gt;|REPLIED&gt;'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Combines the behaviors above.</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="sect4">
<h5 id="_starting_the_sequence_at_one_off_from_the_start_node_2"><a class="link" href="#_starting_the_sequence_at_one_off_from_the_start_node_2">Starting the sequence at one-off from the start node</a></h5>
<div class="paragraph">
<p>There are some uses cases where the sequence does not begin at the start node, but at one node distant.</p>
</div>
<div class="paragraph">
<p>A new config parameter, <code>beginSequenceAtStart</code>, can toggle this behavior.</p>
</div>
<div class="paragraph">
<p>Default value is <code>true</code>.</p>
</div>
<div class="paragraph">
<p>If set to <code>false</code>, this changes the expected values for <code>labelFilter</code>, <code>relationshipFilter</code>, and <code>sequence</code> as noted below:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">sequence</th>
<th class="tableblock halign-left valign-top">altered behavior</th>
<th class="tableblock halign-left valign-top">example</th>
<th class="tableblock halign-left valign-top">explanation</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>labelFilter</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>The start node is not considered part of the sequence. The sequence begins one node off from the start node.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>beginSequenceAtStart:false, labelFilter:'Post|-Blocked,Reply,&gt;Admin'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>The next node(s) out from the start node begins the sequence (and must be a :Post node that isn&#8217;t :Blocked), and only paths ending with <code>Admin</code> nodes returned.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>relationshipFilter</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>The first relationship filter in the sequence string will not be considered part of the repeating sequence, and will only be used for the first relationship from the start node to the node that will be the actual start of the sequence.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>beginSequenceAtStart:false, relationshipFilter:'FIRST&gt;,NEXT&gt;,&lt;FROM,POSTED&gt;|REPLIED&gt;'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p><code>FIRST&gt;</code> will be traversed just from the start node to the node that will be the start of the repeating <code>NEXT&gt;,&lt;FROM,POSTED&gt;|REPLIED&gt;</code> sequence.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sequence</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Combines the above two behaviors.</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>beginSequenceAtStart:false, sequence:'FIRST&gt;, Post|-Blocked, NEXT&gt;, Reply, &lt;FROM, &gt;Admin, POSTED&gt;|REPLIED&gt;'</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Combines the behaviors above.</p>
</div></div></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<div class="title">Sequence tips</div>
<p>Label filtering in sequences work together with the <code>endNodes</code>+<code>terminatorNodes</code>, though inclusion of a node must be unanimous.</p>
</div>
<div class="paragraph">
<p>Remember that <code>filterStartNode</code> defaults to <code>false</code> for APOC 3.2.x.x and newer. If you want the start node filtered according to the first step in the sequence, you may need to set this explicitly to <code>true</code>.</p>
</div>
<div class="paragraph">
<p>If you need to limit the number of times a sequence repeats, this can be done with the <code>maxLevel</code> config param (multiply the number of iterations with the size of the nodes in the sequence).</p>
</div>
<div class="paragraph">
<p>As paths are important when expanding sequences, we recommend avoiding <code>apoc.path.subgraphNodes()</code>, <code>apoc.path.subgraphAll()</code>, and <code>apoc.path.spanningTree()</code> when using sequences,
as the configurations that make these efficient at matching to distinct nodes may interfere with sequence pathfinding.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_uniqueness"><a class="link" href="#_uniqueness">Uniqueness</a></h4>
<div class="paragraph">
<p>Uniqueness of nodes and relationships guides the expansion and the returned results.
Uniqueness is only configurable using <code>expandConfig()</code>.</p>
</div>
<div class="paragraph">
<p><code>subgraphNodes()</code>, <code>subgraphAll()</code>, and <code>spanningTree()</code> all use 'NODE_GLOBAL' uniqueness.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">value</th>
<th class="tableblock halign-left valign-top">description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>RELATIONSHIP_PATH</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>For each returned node there&#8217;s a (relationship wise) unique path from the start node to it. This is Cypher&#8217;s default expansion mode.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NODE_GLOBAL</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>A node cannot be traversed more than once. This is what the legacy traversal framework does.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NODE_LEVEL</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Entities on the same level are guaranteed to be unique.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NODE_PATH</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>For each returned node there&#8217;s a unique path from the start node to it.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NODE_RECENT</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>This is like NODE_GLOBAL, but only guarantees uniqueness among the most recent visited nodes, with a configurable count. Traversing a huge graph is quite memory intensive in that it keeps track of all the nodes it has visited.
For huge graphs a traverser can hog all the memory in the JVM, causing OutOfMemoryError. Together with this Uniqueness you can supply a count, which is the number of most recent visited nodes. This can cause a node to be visited more than once, but scales infinitely.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>RELATIONSHIP_GLOBAL</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>A relationship cannot be traversed more than once, whereas nodes can.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>RELATIONSHIP_LEVEL</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Entities on the same level are guaranteed to be unique.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>RELATIONSHIP_RECENT</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>Same as for NODE_RECENT, but for relationships.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NONE</code></p></td>
<td class="tableblock halign-left valign-top"><div><div class="paragraph">
<p>No restriction (the user will have to manage it)</p>
</div></div></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_end_nodes_and_terminator_nodes"><a class="link" href="#_end_nodes_and_terminator_nodes">End nodes and terminator nodes</a></h4>
<div class="paragraph">
<p>As of the January 2018 APOC releases, you can optionally use <code>endNodes</code> and <code>terminatorNodes</code> params in the config param map when the end nodes of the expansion are known.</p>
</div>
<div class="paragraph">
<p>When <code>endNodes</code> are present, only these end nodes must be at the end of the expanded paths.
Expansion continues beyond end nodes.
This behavior is similar to the end node filter <code>&gt;</code> in the label filters.</p>
</div>
<div class="paragraph">
<p>Nodes given as <code>terminatorNodes</code> behave just like <code>endNodes</code> (they must be at the end of expanded paths), but stops traversal beyond the terminator nodes.
This behavior is similar to the termination filter <code>/</code> in the label filters.</p>
</div>
<div class="paragraph">
<p><code>endNodes</code> and/or <code>terminatorNodes</code> do not conflict with each other (an end node will be returned even if not present in the terminator nodes, and vice versa),
and they can freely be used along with the labelFilter, but a node can only be included by unanimous agreement from endNodes+terminatoNodes and the labelFilter.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_parallel_node_search"><a class="link" href="#_parallel_node_search">Parallel Node Search</a></h3>
<div class="paragraph">
<p>Utility to find nodes in parallel (if possible). These procedures return a single list of nodes or a list of 'reduced' records with node id, labels, and the properties where the search was executed upon.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 55.5555%;">
<col style="width: 44.4445%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.search.node(labelPropertyMap, searchType, search ) yield node</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A distinct set of Nodes will be returned.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.search.nodeAll(labelPropertyMap, searchType, search ) yield node</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All the found Nodes will be returned.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.search.nodeReduced(labelPropertyMap, searchType, search ) yield id, labels, values</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">A merged set of 'minimal' Node information will be returned. One record per node (-id).</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>call apoc.search.nodeAllReduced(labelPropertyMap, searchType, search ) yield id, labels, values</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">All the found 'minimal' Node information will be returned. One record per label and property.</p></td>
</tr>
</tbody>
</table>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 12.5%;">
<col style="width: 50%;">
<col style="width: 37.5%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>labelPropertyMap</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>'{ label1 : "propertyOne", label2 :["propOne","propTwo"] }'</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(JSON or Map) For every Label-Property combination a search will be executed in parallel (if possible): Label1.propertyOne, label2.propOne and label2.propTwo.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>searchType</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">'exact' or 'contains' or 'starts with' or 'ends with'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Case insensitive string search operators</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>searchType</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">"&lt;", "&gt;", "=", "&lt;&gt;", "&#8656;", "&gt;=", "=~"</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Operators</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>search</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">'Keanu'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">The actual search term (string, number, etc).</p></td>
</tr>
</tbody>
</table>
<div class="listingblock">
<div class="title">example</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.search.nodeAll('{Person: "name",Movie: ["title","tagline"]}','contains','her') YIELD node AS n RETURN n
call apoc.search.nodeReduced({Person: 'born', Movie: ['released']},'&gt;',2000) yield id, labels, properties RETURN *</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_graph_algorithms_work_in_progress"><a class="link" href="#_graph_algorithms_work_in_progress">Graph Algorithms (work in progress)</a></h3>
<div class="paragraph">
<p>Provides some graph algorithms (not very optimized yet)</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.dijkstra(startNode, endNode, 'KNOWS|&lt;WORKS_WITH|IS_MANAGER_OF&gt;', 'distance') YIELD path, weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">run dijkstra with relationship property name as cost function</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.dijkstraWithDefaultWeight(startNode, endNode, 'KNOWS|&lt;WORKS_WITH|IS_MANAGER_OF&gt;',  'distance', 10) YIELD path, weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">run dijkstra with relationship property name as cost function and a default weight if the property does not exist</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.aStar(startNode, endNode, 'KNOWS|&lt;WORKS_WITH|IS_MANAGER_OF&gt;', 'distance','lat','lon')  YIELD path, weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">run A* with relationship property name as cost function</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.aStar(startNode, endNode, 'KNOWS|&lt;WORKS_WITH|IS_MANAGER_OF&gt;', {weight:'dist',default:10, x:'lon',y:'lat'}) YIELD path, weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">run A* with relationship property name as cost function</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.allSimplePaths(startNode, endNode, 'KNOWS|&lt;WORKS_WITH|IS_MANAGER_OF&gt;', 5) YIELD path,  weight</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">run allSimplePaths with relationships given and maxNodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.stats.degrees(relTypesDirections) yield type, direction, total, min, max, mean, p50, p75, p90, p95, p99, p999</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">compute degree distribution in parallel</p></td>
</tr>
</tbody>
</table>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.betweenness(['TYPE',&#8230;&#8203;],nodes,BOTH) YIELD node, score</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">calculate betweenness  centrality for given nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.closeness(['TYPE',&#8230;&#8203;],nodes, INCOMING) YIELD node, score</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">calculate closeness  centrality for given nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.cover(nodeIds) YIELD rel</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">return relationships between this set of nodes</p></td>
</tr>
</tbody>
</table>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.pageRank(nodes) YIELD node, score</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">calculates page rank for given nodes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.pageRankWithConfig(nodes,{iterations:_,types:_}) YIELD node, score</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">calculates page rank for given nodes</p></td>
</tr>
</tbody>
</table>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.community(times,labels,partitionKey,type,direction,weightKey,batchSize)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">simple label propagation kernel</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.cliques(minSize) YIELD clique</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">search the graph and return all maximal cliques at least at  large as the minimum size argument.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.cliquesWithNode(startNode, minSize) YIELD clique</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">search the graph and return all maximal cliques that  are at least as large than the minimum size argument and contain this node</p></td>
</tr>
</tbody>
</table>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.cosineSimilarity([vector1], [vector2])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Compute cosine similarity</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.euclideanDistance([vector1], [vector2])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Compute Euclidean distance</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>apoc.algo.euclideanSimilarity([vector1], [vector2])</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Compute Euclidean similarity</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Example: find the weighted shortest path based on relationship property <code>d</code> from <code>A</code> to <code>B</code> following just <code>:ROAD</code> relationships</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (from:Loc{name:'A'}), (to:Loc{name:'D'})
CALL apoc.algo.dijkstra(from, to, 'ROAD', 'd') yield path as path, weight as weight
RETURN path, weight</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_performance_tests"><a class="link" href="#_performance_tests">Performance Tests</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_import_and_export_to_cypher"><a class="link" href="#_import_and_export_to_cypher">Import and Export to Cypher</a></h3>
<div class="paragraph">
<p>Refers to the issue <a href="https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/439/">#439</a> we documented some performance tests of export and import of a big graph into Cypher format file.
For the test we used a server with this characteristics:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>6 cores</p>
</li>
<li>
<p>Intel&#174; Xeon&#174; CPU E5-1650 v2 @ 3.50GHz</p>
</li>
<li>
<p>128 GB of RAM</p>
</li>
</ul>
</div>
<div class="ulist">
<div class="title">Neo4j configuration</div>
<ul>
<li>
<p>dbms.memory.heap.initial_size=8192m</p>
</li>
<li>
<p>dbms.memory.heap.max_size=8192m</p>
</li>
<li>
<p>dbms.memory.pagecache.size=4g</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>They have not be noticed significative difference with 4 GB of heap memory.</p>
</div>
<div class="ulist">
<div class="title">Graph info</div>
<ul>
<li>
<p>total <strong>nodes</strong> 3.158.994</p>
</li>
<li>
<p>total <strong>relationships</strong> 16.800.936</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Download here <a href="https://dl.dropboxusercontent.com/u/14493611/ldbc_sf001_p006.tgz/">LDBC SF1</a></p>
</div>
</div>
<div class="sect2">
<h3 id="_script_to_execute_all_the_tests"><a class="link" href="#_script_to_execute_all_the_tests">Script to execute all the tests</a></h3>
<div class="paragraph">
<p>We created a script that execute all the tests explained below, you can run it like in this example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">./performanceCypherTest.sh 'neo4jHome' 'userName' 'password' 'address'</code></pre>
</div>
</div>
<div class="paragraph">
<p>the <code>address</code> parameter  is optional, the default address is : bolt://localhost:7687
If you use the LDBC SF1 graph, or another big one is better to change the <code>open files allowed</code> from the default 1024 at last to 40.000.</p>
</div>
<div class="paragraph">
<p>Download <a href="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/script/performanceCypherTest.sh">performanceCypherTest.sh</a></p>
</div>
</div>
<div class="sect2">
<h3 id="_export_all"><a class="link" href="#_export_all">Export all</a></h3>
<div class="sect3">
<h4 id="_batch_size"><a class="link" href="#_batch_size">Batch size</a></h4>
<div class="paragraph">
<p>With the use of the config param <code>batchSize</code> we done some tests with different batch size.
The default value is 20000.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">time ./cypher-shell -u yourUsername -p yourPassword
"call apoc.export.cypher.all('yourPath/exportAll', {format:'neo4j-shell', batchSize: 10000})"</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_results_2"><a class="link" href="#_results_2">Results</a></h5>
<div class="listingblock">
<div class="title">Default 20.000</div>
<div class="content">
<pre>real 1m52.744s
user 0m0.936s
sys 0m0.064s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">Batch size 10.000</div>
<div class="content">
<pre>real    1m50.715s
user    0m0.932s
sys     0m0.076s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">Batch size 1.000</div>
<div class="content">
<pre>real    1m49.577s
user    0m0.888s
sys     0m0.120s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">Batch size 100</div>
<div class="content">
<pre>real    1m51.297s
user    0m0.928s
sys     0m0.088s</pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_different_output_formats"><a class="link" href="#_different_output_formats">Different output formats</a></h4>
<div class="paragraph">
<p>We try the different output formats, changing the <code>config</code> parameter <code>format</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">time ./cypher-shell -u yourUsername -p yourPassword  
"call apoc.export.cypher.all('yourPath/exportData.cypher', {format:'neo4j-shell'})"</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_results_3"><a class="link" href="#_results_3">Results</a></h5>
<div class="listingblock">
<div class="title">neo4j-shell</div>
<div class="content">
<pre>real    1m49.268s
user    0m0.904s
sys     0m0.072s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">cypher-shell</div>
<div class="content">
<pre>real    1m55.089s
user    0m0.892s
sys     0m0.092s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">plain</div>
<div class="content">
<pre>real    1m54.490s
user    0m0.932s
sys     0m0.076s</pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_many_files_separatefiles_config"><a class="link" href="#_many_files_separatefiles_config">Many files (separateFiles config)</a></h4>
<div class="paragraph">
<p>With the param <code>separateFiles</code> (default false) we can export our graph or part of it, in different files.
In the example below we name the exported file <code>exportAll.cypher</code> so our export will be:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>exportAll.cleanup.cypher</p>
</li>
<li>
<p>exportAll.nodes.cypher</p>
</li>
<li>
<p>exportAll.relationships.cypher</p>
</li>
<li>
<p>exportAll.schema.cypher</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">time ./cypher-shell -u yourUsername -p yourPassword  
"call apoc.export.cypher.all('yourPath/exportAll.cypher', {format:'neo4j-shell',separateFiles:true})"</code></pre>
</div>
</div>
<div class="sect4">
<h5 id="_result"><a class="link" href="#_result">Result</a></h5>
<div class="listingblock">
<div class="content">
<pre>real 1m55.229s
user 0m0.960s
sys  0m0.084s</pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_export_from_query"><a class="link" href="#_export_from_query">Export from query</a></h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">time ./cypher-shell -u yourUsername -p yourPassword
"call apoc.export.cypher.query('MATCH (n) OPTIONAL MATCH p = (n)-[r]-(m) RETURN n,r,m',
'yourPath/exportQuery.cypher', {format:'neo4j-shell', batchSize: 10000})"</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_result_2"><a class="link" href="#_result_2">Result</a></h4>
<div class="listingblock">
<div class="content">
<pre>real    3m34.924s
user    0m0.992s
sys     0m0.068s</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_export_from_given_nodes_and_rels"><a class="link" href="#_export_from_given_nodes_and_rels">Export from given nodes and rels</a></h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">time ./cypher-shell -u yourUsername -p yourPassword  "Match (n:Person)-[r:LIKES_COMMENT]->(c:Comment)
with collect(n) as colN, collect(c) as colC, collect(r) as colR
CALL apoc.export.cypher.data(colN+colC,colR, 'yourPath/exportData.cypher',{format:'plain'}) YIELD nodes, relationships
RETURN nodes, relationships"</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_result_3"><a class="link" href="#_result_3">Result</a></h4>
<div class="listingblock">
<div class="content">
<pre>real    2m30.576s
user    0m6.264s
sys     0m0.372s</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_export_from_graph_object"><a class="link" href="#_export_from_graph_object">Export from graph object</a></h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">time ./cypher-shell -u yourUsername -p yourPassword "CALL apoc.graph.fromDB('test',{})
yield graph CALL apoc.export.cypher.graph(graph, 'yourPath/exportGraph.cypher',null)
YIELD nodes, relationships
RETURN nodes, relationships"</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_result_4"><a class="link" href="#_result_4">Result</a></h4>
<div class="listingblock">
<div class="title">no config options</div>
<div class="content">
<pre>real    4m50.006s
user    17m26.149s
sys     0m13.145s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">cypher shell</div>
<div class="content">
<pre>real    5m6.467s
user    19m14.328s
sys     0m11.821s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">batch size 1.000</div>
<div class="content">
<pre>real    4m57.598s
user    17m26.557s
sys     0m13.465s</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_import_schema_file"><a class="link" href="#_import_schema_file">Import Schema file</a></h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">time ./cypher-shell -u yourUsername -p yourPassword
"call apoc.cypher.runSchemaFile('yourPath/exportPlain.schema.cypher')"</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_result_5"><a class="link" href="#_result_5">Result</a></h4>
<div class="listingblock">
<div class="content">
<pre>real    0m0.683s
user    0m0.896s
sys     0m0.092s</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_import_from_file"><a class="link" href="#_import_from_file">Import from file</a></h3>
<div class="sect3">
<h4 id="_runfile"><a class="link" href="#_runfile">runFile</a></h4>
<div class="paragraph">
<p>The <code>runFile</code> procedure takes much time to import from files like the ones we&#8217;ve generated before.
These file has more than 19.000.000 rows.
It was created an issue about this <a href="https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/500">#500</a>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">time ./cypher-shell -u yourUsername -p yourPassword
"call apoc.cypher.runFile('yourPath/import/exportPlain.cypher')"</code></pre>
</div>
</div>
<div class="paragraph">
<p>With this command we import not more than 10/15 nodes per second.</p>
</div>
</div>
<div class="sect3">
<h4 id="_import_cypher_shell"><a class="link" href="#_import_cypher_shell">Import cypher-shell</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">time ./cypher-shell -u yourUsername -p yourPassword
< 'yourPath/import/exportCypherShell.cypher'
> 'yourPath/cypherShellOutput'</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Result</div>
<div class="content">
<pre>real    890m38.003s
user    43m34.935s
sys     23m10.951s</pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>imported nodes 3.158.994</p>
</li>
<li>
<p>imported relationships 16.800.936</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_import_neo4j_shell"><a class="link" href="#_import_neo4j_shell">Import neo4j-shell</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">time ./neo4j-shell -u yourUsername -p yourPassword -file
< 'yourPath/import/exportNeo4jShell.cypher'
> 'yourPath/neo4jShellOutput'</code></pre>
</div>
</div>
<div class="paragraph">
<p>We tried to import the DB via neo4j-shell, but after 24 hours it was still uploading.
We tried with a subset of the graph :</p>
</div>
<div class="ulist">
<ul>
<li>
<p>130.000 nodes</p>
</li>
<li>
<p>500.000 relationships</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The result is that neo4j-shell is 7 times slower than the cypher-shell.</p>
</div>
<div class="paragraph">
<div class="title">Result</div>
<p>Cypher-shell</p>
</div>
<div class="listingblock">
<div class="content">
<pre>real    14m43.923s
user    1m1.448s
sys     0m48.556s</pre>
</div>
</div>
<div class="paragraph">
<p>Neo4j-shell</p>
</div>
<div class="listingblock">
<div class="content">
<pre>real    98m54.617s
user    21m5.140s
sys     37m35.852s</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_import_and_export_to_graphml"><a class="link" href="#_import_and_export_to_graphml">Import and Export to GraphML</a></h3>
<div class="paragraph">
<p>Refers to the issue <a href="https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/440">#440</a> we documented some performance tests of export and import of a big graph
into GraphML format.</p>
</div>
</div>
<div class="sect2">
<h3 id="_script_to_execute_all_the_tests_2"><a class="link" href="#_script_to_execute_all_the_tests_2">Script to execute all the tests</a></h3>
<div class="paragraph">
<p>We created a script that execute all the tests explained below, you can run it like in this example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">./performanceGraphmlTest.sh 'neo4jHome' 'userName' 'password' 'address'</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_export_all_2"><a class="link" href="#_export_all_2">Export all</a></h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.export.graphml.all('yourPath/exportAll.graphml',null)</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_results_4"><a class="link" href="#_results_4">Results</a></h4>
<div class="listingblock">
<div class="title">no configuration params</div>
<div class="content">
<pre>real    1m25.530s
user    0m0.968s
sys     0m0.068s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">useTypes</div>
<div class="content">
<pre>real    1m53.521s
user    0m0.908s
sys     0m0.096s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">storeNodeIds</div>
<div class="content">
<pre>real    1m26.898s
user    0m0.900s
sys     0m0.096s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">readLabels</div>
<div class="content">
<pre>real    1m30.592s
user    0m0.916s
sys     0m0.116s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">defaultRelationshipType</div>
<div class="content">
<pre>real    1m30.829s
user    0m0.928s
sys     0m0.068s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">Full config</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.export.graphml.all('yourPath/exportAll.graphml',{storeNodeIds:true, readLabels:true, useTypes:true, defaultRelationshipType:'RELATED'})</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_export_graphml_from_query"><a class="link" href="#_export_graphml_from_query">Export GraphML from query</a></h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.export.graphml.query(
'MATCH (n) OPTIONAL MATCH p = (n)-[r]-(m) RETURN n,r,m',
 'yourPath/exportQuery.graphml', {useTypes:true})</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_results_5"><a class="link" href="#_results_5">Results</a></h4>
<div class="listingblock">
<div class="title">no config</div>
<div class="content">
<pre>real    3m2.257s
user    0m0.972s
sys     0m0.084s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">useTypes</div>
<div class="content">
<pre>real    3m15.295s
user    0m0.860s
sys     0m0.132s</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_export_graphml_from_graph_object"><a class="link" href="#_export_graphml_from_graph_object">Export GraphML from Graph object</a></h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">CALL apoc.graph.fromDB('test',{}) yield graph
CALL apoc.export.graphml.graph(graph, 'yourPath/exportGraph.graphml',null)
YIELD nodes, relationships, properties, file, source,format, time
RETURN *</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_results_6"><a class="link" href="#_results_6">Results</a></h4>
<div class="listingblock">
<div class="title">no config params</div>
<div class="content">
<pre>real    4m12.586s
user    15m27.490s
sys     0m20.609s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">useTypes</div>
<div class="content">
<pre>real    4m44.876s
user    16m46.379s
sys     0m13.421s</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_export_graphml_from_given_nodes_and_rels"><a class="link" href="#_export_graphml_from_given_nodes_and_rels">Export GraphML from given nodes and rels</a></h3>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">MATCH (n:Person)-[r:LIKES_COMMENT]-&gt;(c:Comment)
WITH collect(n) as colN, collect(c) as colC, collect(r) as colR
CALL apoc.export.cypher.data(colN+colC,colR, 'yourPath/exportData.graphml',{useTypes:true})
YIELD nodes, relationships
RETURN 'none'</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="_results_7"><a class="link" href="#_results_7">Results</a></h4>
<div class="listingblock">
<div class="title">no config params</div>
<div class="content">
<pre>real    3m54.067s
user    0m6.648s
sys     0m0.496s</pre>
</div>
</div>
<div class="listingblock">
<div class="title">useTypes</div>
<div class="content">
<pre>real    4m29.370s
user    0m6.676s
sys     0m0.436s</pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_import_graphml"><a class="link" href="#_import_graphml">Import GraphML</a></h3>
<div class="paragraph">
<p>Test of import in a blank database of the export files created before</p>
</div>
<div class="listingblock">
<div class="title">Only batch size as parameter</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">call apoc.import.graphml('yourPath/exportAll.graphml',{batchSize: 10000})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>real    6m50.497s
user    0m1.032s
sys     0m0.084s</pre>
</div>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">file</th>
<th class="tableblock halign-left valign-top">source</th>
<th class="tableblock halign-left valign-top">format</th>
<th class="tableblock halign-left valign-top">nodes</th>
<th class="tableblock halign-left valign-top">relationships</th>
<th class="tableblock halign-left valign-top">properties</th>
<th class="tableblock halign-left valign-top">time</th>
<th class="tableblock halign-left valign-top">rows</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'yourPath/exportAll.graphml'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">"file"</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">"graphml"</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3158994</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16800936</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">42538498</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">409761</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Like we can see from the output we have the same number of nodes and relationship.</p>
</div>
<div class="listingblock">
<div class="title">With parameters</div>
<div class="content">
<pre class="highlight"><code class="language-cypher" data-lang="cypher">"call apoc.import.graphml('yourPath/exportAllConfig.graphml',
{batchSize: 10000, readLabels: true, storeNodeIds: false, defaultRelationshipType:'RELATED'})</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>real    6m44.330s
user    0m0.976s
sys     0m0.100s</pre>
</div>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">file</th>
<th class="tableblock halign-left valign-top">source</th>
<th class="tableblock halign-left valign-top">format</th>
<th class="tableblock halign-left valign-top">nodes</th>
<th class="tableblock halign-left valign-top">relationships</th>
<th class="tableblock halign-left valign-top">properties</th>
<th class="tableblock halign-left valign-top">time</th>
<th class="tableblock halign-left valign-top">rows</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">'yourPath/exportAll.graphml'</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">"file"</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">"graphml"</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">3158994</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16800936</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">22578568</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">403615</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
</tr>
</tbody>
</table>
<div class="sect3">
<h4 id="_import_on_gephi"><a class="link" href="#_import_on_gephi">Import on Gephi</a></h4>
<div class="paragraph">
<p>We tried to import a subset of the graph on <strong>Gephi</strong> :</p>
</div>
<div class="ulist">
<ul>
<li>
<p>25.000 nodes</p>
</li>
<li>
<p>1.000.000 relationships</p>
</li>
<li>
<p>153.000 properties</p>
</li>
</ul>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/import_gephi.png" alt="import gephi" width="800">
</div>
</div>
<div class="paragraph">
<p>The file has been imported in few seconds.</p>
</div>
</div>
<div class="sect3">
<h4 id="_import_on_yed"><a class="link" href="#_import_on_yed">Import on yEd</a></h4>
<div class="paragraph">
<p>With the same subset we tried to import it on <strong>yEd</strong>.
The export file has to convert into UTF-8.</p>
</div>
<div class="imageblock">
<div class="content">
<img src="https://raw.githubusercontent.com/neo4j-contrib/neo4j-apoc-procedures/3.2/docs/img/import_yed.png" alt="import yed" width="800">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2018-02-23 22:58:48 MEZ
</div>
</div>
</body>
</html>